jaco_manipulation.cpp
Go to the documentation of this file.
00001 #include <wpi_jaco_wrapper/jaco_manipulation.h>
00002 
00003 using namespace std;
00004 
00005 JacoManipulation::JacoManipulation() : pnh("~")
00006 {
00007   pnh.param("kinova_gripper", kinova_gripper_, true);
00008   loadParameters(n);
00009 
00010   if (kinova_gripper_)
00011   {
00012     acGripper = new GripperClient(n, topic_prefix_ + "_arm/fingers_controller/gripper", true);
00013     asGripper = new GripperServer(n, topic_prefix_ + "_arm/manipulation/gripper", boost::bind(&JacoManipulation::execute_gripper, this, _1), false);
00014   }
00015   asLift    = new LiftServer(n, topic_prefix_ + "_arm/manipulation/lift", boost::bind(&JacoManipulation::execute_lift, this, _1), false);
00016 
00017   // Messages
00018   cartesianCmdPublisher = n.advertise<wpi_jaco_msgs::CartesianCommand>(topic_prefix_ + "_arm/cartesian_cmd", 1);
00019   angularCmdPublisher = n.advertise<wpi_jaco_msgs::AngularCommand>(topic_prefix_ + "_arm/angular_cmd", 1);
00020 
00021   jointStateSubscriber = n.subscribe(topic_prefix_ + "_arm/joint_states", 1, &JacoManipulation::jointStateCallback, this);
00022 
00023   // Services
00024   cartesianPositionClient = n.serviceClient<wpi_jaco_msgs::GetCartesianPosition>(topic_prefix_ + "_arm/get_cartesian_position");
00025   eraseTrajectoriesClient = n.serviceClient<std_srvs::Empty>(topic_prefix_ + "_arm/erase_trajectories");
00026 
00027   if (kinova_gripper_)
00028   {
00029     ROS_INFO("Waiting for gripper action server...");
00030     acGripper->waitForServer();
00031     ROS_INFO("Finished waiting for action server.");
00032   }
00033 
00034   // Action servers
00035   if (kinova_gripper_)
00036     asGripper->start();
00037   asLift->start();
00038 }
00039 
00040 bool JacoManipulation::loadParameters(const ros::NodeHandle n)
00041 {
00042     ROS_DEBUG("Loading parameters");
00043 
00044     n.param("wpi_jaco/arm_name", arm_name_, std::string("jaco"));
00045     n.param("wpi_jaco/gripper_closed", gripper_closed_, 0.0);
00046     n.param("wpi_jaco/gripper_open", gripper_open_, 65.0);
00047     n.param("wpi_jaco/num_fingers", num_fingers_, 3);
00048 
00049     // Update topic prefix
00050     if (arm_name_ == "jaco2")
00051       topic_prefix_ = "jaco";
00052     else
00053       topic_prefix_ = arm_name_;
00054 
00055     if (kinova_gripper_)
00056       num_joints_ = num_fingers_ + NUM_JACO_JOINTS;
00057     else
00058       num_joints_ = NUM_JACO_JOINTS;
00059 
00060     joint_pos_.resize(num_joints_);
00061 
00062     ROS_INFO("arm_name: %s", arm_name_.c_str());
00063 
00064     ROS_INFO("Parameters loaded.");
00065 
00067     return true;
00068 }
00069 
00070 void JacoManipulation::jointStateCallback(const sensor_msgs::JointState msg)
00071 {
00072   for (unsigned int i = 0; i < num_joints_; i++)
00073     joint_pos_[i] = msg.position[i];
00074 }
00075 
00076 void JacoManipulation::execute_gripper(const rail_manipulation_msgs::GripperGoalConstPtr &goal)
00077 {
00078   rail_manipulation_msgs::GripperResult result;
00079 
00080   if (asLift->isActive())
00081   {
00082     asGripper->setPreempted();
00083     ROS_INFO("Lift server already running, grasp action preempted");
00084     return;
00085   }
00086 
00087   float startingFingerPos[3];
00088   for (int i = 0 ; i < num_fingers_ ; i++)
00089     startingFingerPos[i] = joint_pos_[NUM_JACO_JOINTS+i];
00090 
00091   //check if grasp is already finished (for opening case only)
00092   if (!goal->close)
00093   {
00094     bool gripper_open = true;
00095     for (int i = 0 ; i < num_fingers_ ; i++)
00096       gripper_open = gripper_open && startingFingerPos[i] <= GRIPPER_OPEN_THRESHOLD;
00097 
00098     if (gripper_open)
00099     {
00100       ROS_INFO("Gripper is open.");
00101       result.success = true;
00102       asGripper->setSucceeded(result, "Open gripper action succeeded, as the gripper is already open.");
00103       return;
00104     }
00105   }
00106 
00107   control_msgs::GripperCommandGoal gripperGoal;
00108   if (goal->close)
00109     gripperGoal.command.position = gripper_closed_;
00110   else
00111     gripperGoal.command.position = gripper_open_;
00112   acGripper->sendGoal(gripperGoal);
00113 
00114   ros::Rate loopRate(30);
00115   while (!acGripper->getState().isDone())
00116   {
00117     //check for preempt requests from clients
00118     if (asGripper->isPreemptRequested() || !ros::ok())
00119     {
00120       acGripper->cancelAllGoals();
00121       //preempt action server
00122       asGripper->setPreempted();
00123       ROS_INFO("Gripper action server preempted by client");
00124       return;
00125     }
00126     loopRate.sleep();
00127   }
00128 
00129   rail_manipulation_msgs::GripperResult serverResult;
00130   //success occurs if the gripper has moved, as it is unlikely to reach the final "closed" position when grasping an object
00131   //serverResult.success = acGripper->getResult()->reached_goal;
00132   if (goal->close)
00133   {
00134     bool gripper_closing = false;
00135     for (int i = 0 ; i < num_fingers_ ; i++)
00136       gripper_closing = gripper_closing || joint_pos_[NUM_JACO_JOINTS+i] > startingFingerPos[i];
00137 
00138     serverResult.success = gripper_closing;
00139   }
00140   else
00141   {
00142     bool gripper_opening = false;
00143     for (int i = 0 ; i < num_fingers_ ; i++)
00144       gripper_opening = gripper_opening || joint_pos_[NUM_JACO_JOINTS+i] < startingFingerPos[i];
00145 
00146     serverResult.success = gripper_opening;
00147   }
00148   asGripper->setSucceeded(serverResult);
00149   ROS_INFO("Gripper action finished.");
00150 }
00151 
00152 void JacoManipulation::execute_lift(rail_manipulation_msgs::LiftGoalConstPtr const &goal)
00153 {
00154   if (kinova_gripper_)
00155   {
00156     if (asGripper->isActive())
00157     {
00158       asLift->setPreempted();
00159       ROS_INFO("Gripper server already running, lift action preempted");
00160       return;
00161     }
00162   }
00163 
00164   //get initial end effector height
00165   wpi_jaco_msgs::GetCartesianPosition srv;
00166   rail_manipulation_msgs::LiftResult result;
00167   if (cartesianPositionClient.call(srv))
00168   {
00169     float initialZ = srv.response.pos.linear.z;
00170 
00171     //populate the velocity command
00172     wpi_jaco_msgs::CartesianCommand cmd;
00173     cmd.position = false;
00174     cmd.armCommand = true;
00175     cmd.fingerCommand = true;
00176     cmd.repeat = true;
00177     cmd.fingers.resize(3);
00178     cmd.arm.linear.x = 0.0;
00179     cmd.arm.linear.y = 0.0;
00180     cmd.arm.linear.z = DEFAULT_LIFT_VEL;
00181     cmd.arm.angular.x = 0.0;
00182     cmd.arm.angular.y = 0.0;
00183     cmd.arm.angular.z = 0.0;
00184     cmd.fingers[0] = MAX_FINGER_VEL;
00185     cmd.fingers[1] = MAX_FINGER_VEL;
00186     cmd.fingers[2] = MAX_FINGER_VEL;
00187 
00188     bool finished = false;
00189     float currentZ;
00190     double startTime = ros::Time::now().toSec();
00191 
00192     //send the lift and close command until a certain height has been reached, or the
00193     //action times out
00194     while (!finished)
00195     {
00196       //check for preempt requests from clients
00197       if (asLift->isPreemptRequested() || !ros::ok())
00198       {
00199         //stop pickup action
00200         std_srvs::Empty emptySrv;
00201         if(!eraseTrajectoriesClient.call(emptySrv))
00202         {
00203           ROS_INFO("Could not call erase trajectories service");
00204         }
00205 
00206         //preempt action server
00207         asLift->setPreempted();
00208         ROS_INFO("Lift action server preempted by client");
00209 
00210         return;
00211       }
00212 
00213       cartesianCmdPublisher.publish(cmd);
00214 
00215       if (cartesianPositionClient.call(srv))
00216       {
00217         currentZ = srv.response.pos.linear.z;
00218       }
00219       else
00220       {
00221         ROS_INFO("Couldn't call Cartesian position server");
00222         result.success = false;
00223         break;
00224       }
00225 
00226       if (currentZ - initialZ >= LIFT_HEIGHT)
00227       {
00228         finished = true;
00229         result.success = true;
00230       }
00231       else if (ros::Time::now().toSec() - startTime >= LIFT_TIMEOUT)
00232       {
00233         finished = true;
00234         result.success = false;
00235       }
00236     }
00237 
00238     //stop arm
00239     std_srvs::Empty emptySrv;
00240     if(!eraseTrajectoriesClient.call(emptySrv))
00241     {
00242       ROS_INFO("Could not call erase trajectories service");
00243     }
00244   }
00245   else
00246   {
00247     ROS_INFO("Couldn't call Cartesian position server");
00248     result.success = false;
00249   }
00250 
00251   asLift->setSucceeded(result);
00252   ROS_INFO("Pickup execution complete");
00253 
00254 }
00255 
00256 int main(int argc, char** argv)
00257 {
00258   ros::init(argc, argv, "jaco_manipulation");
00259 
00260   JacoManipulation jm;
00261 
00262   ros::spin();
00263 }


wpi_jaco_wrapper
Author(s): David Kent
autogenerated on Thu Jun 6 2019 19:43:31