jaco_interactive_manipulation.cpp
Go to the documentation of this file.
00001 #include <jaco_interaction/jaco_interactive_manipulation.h>
00002 
00003 using namespace std;
00004 
00005 JacoInteractiveManipulation::JacoInteractiveManipulation() :
00006     acGripper("jaco_arm/manipulation/gripper", true), acLift("jaco_arm/manipulation/lift", true), acHome(
00007         "jaco_arm/home_arm", true)
00008 {
00009   loadParameters(n);
00010 
00011   joints.resize(6);
00012 
00013   //messages
00014   cartesianCmd = n.advertise<wpi_jaco_msgs::CartesianCommand>("jaco_arm/cartesian_cmd", 1);
00015   jointStateSubscriber = n.subscribe("jaco_arm/joint_states", 1, &JacoInteractiveManipulation::updateJoints, this);
00016 
00017   //services
00018   eraseTrajectoriesClient = n.serviceClient<std_srvs::Empty>("jaco_arm/erase_trajectories");
00019   jacoFkClient = n.serviceClient<wpi_jaco_msgs::JacoFK>("jaco_arm/kinematics/fk");
00020   qeClient = n.serviceClient<wpi_jaco_msgs::QuaternionToEuler>("jaco_conversions/quaternion_to_euler");
00021 
00022   //actionlib
00023   ROS_INFO("Waiting for grasp, pickup, and home arm action servers...");
00024   acGripper.waitForServer();
00025   acLift.waitForServer();
00026   acHome.waitForServer();
00027   ROS_INFO("Finished waiting for action servers");
00028 
00029   lockPose = false;
00030 
00031   imServer.reset(
00032       new interactive_markers::InteractiveMarkerServer("jaco_interactive_manipulation", "jaco_markers", false));
00033 
00034   ros::Duration(0.1).sleep();
00035 
00036   makeHandMarker();
00037 
00038   imServer->applyChanges();
00039 }
00040 
00041 void JacoInteractiveManipulation::updateJoints(const sensor_msgs::JointState::ConstPtr& msg)
00042 {
00043   for (unsigned int i = 0; i < 6; i++)
00044   {
00045     joints.at(i) = msg->position.at(i);
00046   }
00047 }
00048 
00049 void JacoInteractiveManipulation::makeHandMarker()
00050 {
00051   visualization_msgs::InteractiveMarker iMarker;
00052   if (arm_name_ == "jaco2")
00053     iMarker.header.frame_id = "jaco_base_link";
00054   else
00055     iMarker.header.frame_id = "jaco_link_base";
00056 
00057   //initialize position to the jaco arm's current position
00058   wpi_jaco_msgs::JacoFK fkSrv;
00059   for (unsigned int i = 0; i < 6; i++)
00060   {
00061     fkSrv.request.joints.push_back(joints.at(i));
00062   }
00063   if (jacoFkClient.call(fkSrv))
00064   {
00065     iMarker.pose = fkSrv.response.handPose.pose;
00066   }
00067   else
00068   {
00069     iMarker.pose.position.x = 0.0;
00070     iMarker.pose.position.y = 0.0;
00071     iMarker.pose.position.z = 0.0;
00072     iMarker.pose.orientation.x = 0.0;
00073     iMarker.pose.orientation.y = 0.0;
00074     iMarker.pose.orientation.z = 0.0;
00075     iMarker.pose.orientation.w = 1.0;
00076   }
00077   iMarker.scale = .2;
00078 
00079   iMarker.name = "jaco_hand_marker";
00080   iMarker.description = "JACO Hand Control";
00081 
00082   //make a sphere control to represent the end effector position
00083   visualization_msgs::Marker sphereMarker;
00084   sphereMarker.type = visualization_msgs::Marker::SPHERE;
00085   sphereMarker.scale.x = iMarker.scale * 1;
00086   sphereMarker.scale.y = iMarker.scale * 1;
00087   sphereMarker.scale.z = iMarker.scale * 1;
00088   sphereMarker.color.r = .5;
00089   sphereMarker.color.g = .5;
00090   sphereMarker.color.b = .5;
00091   sphereMarker.color.a = 0.0;
00092   visualization_msgs::InteractiveMarkerControl sphereControl;
00093   sphereControl.markers.push_back(sphereMarker);
00094   sphereControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00095   sphereControl.name = "jaco_hand_origin_marker";
00096   iMarker.controls.push_back(sphereControl);
00097 
00098   //add 6-DOF controls
00099   visualization_msgs::InteractiveMarkerControl control;
00100 
00101   control.orientation.w = 1;
00102   control.orientation.x = 1;
00103   control.orientation.y = 0;
00104   control.orientation.z = 0;
00105   control.name = "rotate_x";
00106   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00107   iMarker.controls.push_back(control);
00108   control.name = "move_x";
00109   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00110   iMarker.controls.push_back(control);
00111 
00112   control.orientation.w = 1;
00113   control.orientation.x = 0;
00114   control.orientation.y = 1;
00115   control.orientation.z = 0;
00116   control.name = "rotate_y";
00117   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00118   iMarker.controls.push_back(control);
00119   control.name = "move_y";
00120   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00121   iMarker.controls.push_back(control);
00122 
00123   control.orientation.w = 1;
00124   control.orientation.x = 0;
00125   control.orientation.y = 0;
00126   control.orientation.z = 1;
00127   control.name = "rotate_z";
00128   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00129   iMarker.controls.push_back(control);
00130   control.name = "move_z";
00131   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00132   iMarker.controls.push_back(control);
00133 
00134   //menu
00135   interactive_markers::MenuHandler::EntryHandle fingersSubMenuHandle = menuHandler.insert("Gripper");
00136   menuHandler.insert(fingersSubMenuHandle, "Close",
00137                      boost::bind(&JacoInteractiveManipulation::processHandMarkerFeedback, this, _1));
00138   menuHandler.insert(fingersSubMenuHandle, "Open",
00139                      boost::bind(&JacoInteractiveManipulation::processHandMarkerFeedback, this, _1));
00140   menuHandler.insert("Pickup", boost::bind(&JacoInteractiveManipulation::processHandMarkerFeedback, this, _1));
00141   menuHandler.insert("Home", boost::bind(&JacoInteractiveManipulation::processHandMarkerFeedback, this, _1));
00142   menuHandler.insert("Retract", boost::bind(&JacoInteractiveManipulation::processHandMarkerFeedback, this, _1));
00143 
00144   visualization_msgs::InteractiveMarkerControl menuControl;
00145   menuControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::MENU;
00146   menuControl.name = "jaco_hand_menu";
00147   iMarker.controls.push_back(menuControl);
00148 
00149   imServer->insert(iMarker);
00150   imServer->setCallback(iMarker.name, boost::bind(&JacoInteractiveManipulation::processHandMarkerFeedback, this, _1));
00151 
00152   menuHandler.apply(*imServer, iMarker.name);
00153 }
00154 
00155 void JacoInteractiveManipulation::processHandMarkerFeedback(
00156     const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00157 {
00158   switch (feedback->event_type)
00159   {
00160     //Send a stop command so that when the marker is released the arm stops moving
00161     case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
00162       if (feedback->marker_name.compare("jaco_hand_marker") == 0)
00163       {
00164         lockPose = true;
00165         sendStopCommand();
00166       }
00167       break;
00168 
00169       //Menu actions
00170     case visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT:
00171       if (feedback->marker_name.compare("jaco_hand_marker") == 0)
00172       {
00173         if (feedback->menu_entry_id == 2)       //grasp requested
00174         {
00175           rail_manipulation_msgs::GripperGoal gripperGoal;
00176           gripperGoal.close = true;
00177           acGripper.sendGoal(gripperGoal);
00178         }
00179         else if (feedback->menu_entry_id == 3)  //release requested
00180         {
00181           rail_manipulation_msgs::GripperGoal gripperGoal;
00182           gripperGoal.close = false;
00183           acGripper.sendGoal(gripperGoal);
00184         }
00185         else if (feedback->menu_entry_id == 4)  //pickup requested
00186         {
00187           rail_manipulation_msgs::LiftGoal liftGoal;
00188           acLift.sendGoal(liftGoal);
00189         }
00190         else if (feedback->menu_entry_id == 5)  //home requested
00191         {
00192           acGripper.cancelAllGoals();
00193           acLift.cancelAllGoals();
00194           wpi_jaco_msgs::HomeArmGoal homeGoal;
00195           homeGoal.retract = false;
00196           acHome.sendGoal(homeGoal);
00197           acHome.waitForResult(ros::Duration(10.0));
00198         }
00199         else if (feedback->menu_entry_id == 6)
00200         {
00201           acGripper.cancelAllGoals();
00202           acLift.cancelAllGoals();
00203           wpi_jaco_msgs::HomeArmGoal homeGoal;
00204           homeGoal.retract = true;
00205           homeGoal.retractPosition.position = true;
00206           homeGoal.retractPosition.armCommand = true;
00207           homeGoal.retractPosition.fingerCommand = false;
00208           homeGoal.retractPosition.repeat = false;
00209           homeGoal.retractPosition.joints.resize(6);
00210           homeGoal.retractPosition.joints[0] = -2.57;
00211           homeGoal.retractPosition.joints[1] = 1.39;
00212           homeGoal.retractPosition.joints[2] = .527;
00213           homeGoal.retractPosition.joints[3] = -.084;
00214           homeGoal.retractPosition.joints[4] = .515;
00215           homeGoal.retractPosition.joints[5] = -1.745;
00216           acHome.sendGoal(homeGoal);
00217           acHome.waitForResult(ros::Duration(15.0));
00218         }
00219       }
00220       break;
00221 
00222       //Send movement commands to the arm to follow the pose marker
00223     case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
00224       if (feedback->marker_name.compare("jaco_hand_marker") == 0
00225           && feedback->control_name.compare("jaco_hand_origin_marker") != 0)
00226       {
00227         if (!lockPose)
00228         {
00229           acGripper.cancelAllGoals();
00230           acLift.cancelAllGoals();
00231 
00232           //convert pose for compatibility with JACO API
00233           wpi_jaco_msgs::QuaternionToEuler qeSrv;
00234           qeSrv.request.orientation = feedback->pose.orientation;
00235           if (qeClient.call(qeSrv))
00236           {
00237             wpi_jaco_msgs::CartesianCommand cmd;
00238             cmd.position = true;
00239             cmd.armCommand = true;
00240             cmd.fingerCommand = false;
00241             cmd.repeat = false;
00242             cmd.arm.linear.x = feedback->pose.position.x;
00243             cmd.arm.linear.y = feedback->pose.position.y;
00244             cmd.arm.linear.z = feedback->pose.position.z;
00245             cmd.arm.angular.x = qeSrv.response.roll;
00246             cmd.arm.angular.y = qeSrv.response.pitch;
00247             cmd.arm.angular.z = qeSrv.response.yaw;
00248 
00249             cartesianCmd.publish(cmd);
00250           }
00251           else
00252             ROS_INFO("Quaternion to Euler conversion service failed, could not send pose update");
00253         }
00254       }
00255       break;
00256 
00257       //Mouse down events
00258     case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
00259       lockPose = false;
00260       break;
00261 
00262       //As with mouse clicked, send a stop command when the mouse is released on the marker
00263     case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
00264       if (feedback->marker_name.compare("jaco_hand_marker") == 0)
00265       {
00266         lockPose = true;
00267         sendStopCommand();
00268       }
00269       break;
00270   }
00271 
00272   //Update interactive marker server
00273   imServer->applyChanges();
00274 }
00275 
00276 void JacoInteractiveManipulation::sendStopCommand()
00277 {
00278   wpi_jaco_msgs::CartesianCommand cmd;
00279   cmd.position = false;
00280   cmd.armCommand = true;
00281   cmd.fingerCommand = false;
00282   cmd.repeat = true;
00283   cmd.arm.linear.x = 0.0;
00284   cmd.arm.linear.y = 0.0;
00285   cmd.arm.linear.z = 0.0;
00286   cmd.arm.angular.x = 0.0;
00287   cmd.arm.angular.y = 0.0;
00288   cmd.arm.angular.z = 0.0;
00289   cartesianCmd.publish(cmd);
00290 
00291   std_srvs::Empty srv;
00292   if (!eraseTrajectoriesClient.call(srv))
00293   {
00294     ROS_INFO("Could not call erase trajectories service...");
00295   }
00296 }
00297 
00298 void JacoInteractiveManipulation::updateMarkerPosition()
00299 {
00300   wpi_jaco_msgs::JacoFK fkSrv;
00301   for (unsigned int i = 0; i < 6; i++)
00302   {
00303     fkSrv.request.joints.push_back(joints.at(i));
00304   }
00305 
00306   if (jacoFkClient.call(fkSrv))
00307   {
00308     imServer->setPose("jaco_hand_marker", fkSrv.response.handPose.pose);
00309     imServer->applyChanges();
00310   }
00311   else
00312   {
00313     ROS_INFO("Failed to call forward kinematics service");
00314   }
00315 }
00316 
00317 bool JacoInteractiveManipulation::loadParameters(const ros::NodeHandle n)
00318 {
00319   n.param("wpi_jaco/arm_name",                arm_name_,              std::string("jaco"));
00320 
00322   return true;
00323 }
00324 
00325 int main(int argc, char **argv)
00326 {
00327   ros::init(argc, argv, "jaco_interactive_manipulation");
00328 
00329   JacoInteractiveManipulation jim;
00330 
00331   ros::Rate loop_rate(30);
00332   while (ros::ok())
00333   {
00334     jim.updateMarkerPosition();
00335     ros::spinOnce();
00336     loop_rate.sleep();
00337   }
00338 }
00339 


jaco_interaction
Author(s): David Kent
autogenerated on Thu Jun 6 2019 19:43:26