carl_interactive_manipulation.cpp
Go to the documentation of this file.
00001 #include <carl_interactive_manipulation/carl_interactive_manipulation.h>
00002 
00003 using namespace std;
00004 
00005 CarlInteractiveManipulation::CarlInteractiveManipulation() :
00006     acGripper("jaco_arm/manipulation/gripper", true),
00007     acArm("carl_moveit_wrapper/common_actions/arm_action", true),
00008     acPickup("carl_moveit_wrapper/common_actions/pickup", true)
00009 {
00010   joints.resize(6);
00011   lastRetractedFeedback = ros::Time::now();
00012 
00013   //read parameters
00014   ros::NodeHandle pnh("~");
00015   string segmentedObjectsTopic("/object_recognition_listener/recognized_objects");
00016   usingPickup = false;
00017   usingRecognition = false;
00018   pnh.getParam("using_pickup", usingPickup);
00019   pnh.getParam("using_recognition", usingRecognition);
00020 
00021   //messages
00022   cartesianCmd = n.advertise<wpi_jaco_msgs::CartesianCommand>("jaco_arm/cartesian_cmd", 1);
00023   safetyErrorPublisher = n.advertise<carl_safety::Error>("carl_safety/error", 1);
00024   jointStateSubscriber = n.subscribe("jaco_arm/joint_states", 1, &CarlInteractiveManipulation::updateJoints, this);
00025   if (usingRecognition)
00026     recognizedObjectsSubscriber = n.subscribe("object_recognition_listener/recognized_objects", 1, &CarlInteractiveManipulation::segmentedObjectsCallback, this);
00027   else
00028     recognizedObjectsSubscriber = n.subscribe("rail_segmentation/segmented_objects", 1, &CarlInteractiveManipulation::segmentedObjectsCallback, this);
00029 
00030   //services
00031   armCartesianPositionClient = n.serviceClient<wpi_jaco_msgs::GetCartesianPosition>("jaco_arm/get_cartesian_position");
00032   armEStopClient = n.serviceClient<wpi_jaco_msgs::EStop>("jaco_arm/software_estop");
00033   eraseTrajectoriesClient = n.serviceClient<std_srvs::Empty>("jaco_arm/erase_trajectories");
00034   jacoFkClient = n.serviceClient<wpi_jaco_msgs::JacoFK>("jaco_arm/kinematics/fk");
00035   qeClient = n.serviceClient<wpi_jaco_msgs::QuaternionToEuler>("jaco_conversions/quaternion_to_euler");
00036   //pickupSegmentedClient = n.serviceClient<rail_pick_and_place_msgs::PickupSegmentedObject>("rail_pick_and_place/pickup_segmented_object");
00037   if (usingRecognition)
00038     removeObjectClient = n.serviceClient<rail_pick_and_place_msgs::RemoveObject>("/object_recognition_listener/remove_object");
00039   else
00040     removeObjectClient = n.serviceClient<rail_segmentation::RemoveObject>("rail_segmentation/remove_object");
00041   detachObjectsClient = n.serviceClient<std_srvs::Empty>("carl_moveit_wrapper/detach_objects");
00042   armAngularPositionClient = n.serviceClient<wpi_jaco_msgs::GetAngularPosition>("jaco_arm/get_angular_position");
00043 
00044   //actionlib
00045   ROS_INFO("Waiting for grasp action servers...");
00046   acGripper.waitForServer();
00047   acArm.waitForServer();
00048   ROS_INFO("Finished waiting for action servers");
00049 
00050   markerPose.resize(6);
00051   lockPose = false;
00052   movingArm = false;
00053   disableArmMarkerCommands = false;
00054   retractPos.resize(6);
00055   retractPos[0] = -2.57;
00056   retractPos[1] = 1.39;
00057   retractPos[2] = .527;
00058   retractPos[3] = -.084;
00059   retractPos[4] = .515;
00060   retractPos[5] = -1.745;
00061 
00062   imServer.reset(
00063       new interactive_markers::InteractiveMarkerServer("carl_interactive_manipulation", "carl_markers", false));
00064 
00065   ros::Duration(0.1).sleep();
00066 
00067   makeHandMarker();
00068 
00069   //setup object menu
00070   if (usingPickup)
00071     objectMenuHandler.insert("Pickup", boost::bind(&CarlInteractiveManipulation::processPickupMarkerFeedback, this, _1));
00072   objectMenuHandler.insert("Remove", boost::bind(&CarlInteractiveManipulation::processRemoveMarkerFeedback, this, _1));
00073 
00074   imServer->applyChanges();
00075 }
00076 
00077 void CarlInteractiveManipulation::updateJoints(const sensor_msgs::JointState::ConstPtr& msg)
00078 {
00079   for (unsigned int i = 0; i < 6; i++)
00080   {
00081     joints.at(i) = msg->position.at(i);
00082   }
00083 
00084   //perform safety check if arm is moving due to interactive marker Cartesian control
00085   if (movingArm)
00086   {
00087     if (fabs(msg->effort[0]) >= J1_THRESHOLD || fabs(msg->effort[1] >= J2_THRESHOLD) || fabs(msg->effort[2] >= J3_THRESHOLD)
00088         || fabs(msg->effort[3]) >= J4_THRESHOLD || fabs(msg->effort[4] >= J5_THRESHOLD) || fabs(msg->effort[5] >= J6_THRESHOLD)
00089         || fabs(msg->effort[6]) >= F1_THRESHOLD || fabs(msg->effort[7] >= F2_THRESHOLD) || fabs(msg->effort[8] >= F3_THRESHOLD))
00090     {
00091       ROS_INFO("Arm is moving dangerously, attempty recovery...");
00092       armCollisionRecovery();
00093     }
00094   }
00095 }
00096 
00097 void CarlInteractiveManipulation::segmentedObjectsCallback(
00098     const rail_manipulation_msgs::SegmentedObjectList::ConstPtr& objectList)
00099 {
00100   boost::recursive_mutex::scoped_lock lock(api_mutex); //lock for object list
00101 
00102   //store list of objects
00103   segmentedObjectList = *objectList;
00104 
00105   ROS_INFO("Received new segmented point clouds");
00106   clearSegmentedObjects();
00107   recognizedMenuHandlers.clear();
00108   recognizedMenuHandlers.resize(objectList->objects.size());
00109   for (unsigned int i = 0; i < objectList->objects.size(); i++)
00110   {
00111     visualization_msgs::InteractiveMarker objectMarker;
00112     objectMarker.header = objectList->objects[i].marker.header;
00113 
00114     objectMarker.pose.position.x = 0.0;
00115     objectMarker.pose.position.y = 0.0;
00116     objectMarker.pose.position.z = 0.0;
00117     objectMarker.pose.orientation.x = 0.0;
00118     objectMarker.pose.orientation.y = 0.0;
00119     objectMarker.pose.orientation.z = 0.0;
00120     objectMarker.pose.orientation.w = 1.0;
00121 
00122     stringstream ss;
00123     ss.str("");
00124     ss << "object" << i;
00125     objectMarker.name = ss.str();
00126 
00127     visualization_msgs::InteractiveMarkerControl objectControl;
00128     ss << "control";
00129     objectControl.name = ss.str();
00130     objectControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00131     //objectControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::MENU;
00132     objectControl.always_visible = true;
00133     objectControl.markers.resize(1);
00134     //objectControl.markers[0] = cloudMarker;
00135     objectControl.markers[0] = objectList->objects[i].marker;
00136     objectMarker.controls.push_back(objectControl);
00137 
00138     //object label
00139     visualization_msgs::InteractiveMarkerControl objectLabelControl;
00140     stringstream namestream;
00141     namestream.str("");
00142     namestream << "object" << i << "_label";
00143     objectLabelControl.name = namestream.str();
00144     objectLabelControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::NONE;
00145     objectLabelControl.always_visible = true;
00146     visualization_msgs::Marker objectLabel;
00147     objectLabel.header = objectList->objects[i].point_cloud.header;
00148     objectLabel.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00149     objectLabel.pose.position.x = objectList->objects[i].centroid.x;
00150     objectLabel.pose.position.y = objectList->objects[i].centroid.y;
00151     objectLabel.pose.position.z = objectList->objects[i].centroid.z + .1;
00152     objectLabel.scale.x = .1;
00153     objectLabel.scale.y = .1;
00154     objectLabel.scale.z = .1;
00155     objectLabel.color.r = 1.0;
00156     objectLabel.color.g = 1.0;
00157     objectLabel.color.b = 1.0;
00158     objectLabel.color.a = 1.0;
00159     objectLabel.text = objectList->objects[i].name;
00160     objectLabelControl.markers.resize(1);
00161     objectLabelControl.markers[0] = objectLabel;
00162     objectMarker.controls.push_back(objectLabelControl);
00163 
00164     //pickup menu
00165     visualization_msgs::InteractiveMarkerControl objectMenuControl;
00166     objectMenuControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::MENU;
00167     ss << "_menu";
00168     objectMenuControl.name = ss.str();
00169     objectMarker.controls.push_back(objectMenuControl);
00170 
00171     imServer->insert(objectMarker);
00172 
00173     if (objectList->objects[i].recognized)
00174     {
00175       if (usingPickup)
00176       {
00177         stringstream ss2;
00178         ss2.str("");
00179         ss2 << "Pickup " << objectList->objects[i].name;
00180         recognizedMenuHandlers[i].insert(ss2.str(), boost::bind(&CarlInteractiveManipulation::processPickupMarkerFeedback, this, _1));
00181       }
00182       recognizedMenuHandlers[i].insert("Remove", boost::bind(&CarlInteractiveManipulation::processRemoveMarkerFeedback, this, _1));
00183       recognizedMenuHandlers[i].apply(*imServer, objectMarker.name);
00184     }
00185     else
00186     {
00187       objectMenuHandler.apply(*imServer, objectMarker.name);
00188     }
00189 
00190     segmentedObjects.push_back(objectMarker);
00191   }
00192 
00193   imServer->applyChanges();
00194 
00195   ROS_INFO("Point cloud markers created");
00196 }
00197 
00198 void CarlInteractiveManipulation::clearSegmentedObjects()
00199 {
00200   boost::recursive_mutex::scoped_lock lock(api_mutex); //lock for object list
00201 
00202   for (unsigned int i = 0; i < segmentedObjects.size(); i++)
00203   {
00204     stringstream ss;
00205     ss.str("");
00206     ss << "object" << i;
00207     imServer->erase(ss.str());
00208   }
00209   segmentedObjects.clear();
00210 
00211   imServer->applyChanges();
00212 }
00213 
00214 void CarlInteractiveManipulation::makeHandMarker()
00215 {
00216   visualization_msgs::InteractiveMarker iMarker;
00217   iMarker.header.frame_id = "jaco_link_base";
00218 
00219   //initialize position to the jaco arm's current position
00220   wpi_jaco_msgs::JacoFK fkSrv;
00221   for (unsigned int i = 0; i < 6; i++)
00222   {
00223     fkSrv.request.joints.push_back(joints.at(i));
00224   }
00225   if (jacoFkClient.call(fkSrv))
00226   {
00227     iMarker.pose = fkSrv.response.handPose.pose;
00228   }
00229   else
00230   {
00231     iMarker.pose.position.x = 0.0;
00232     iMarker.pose.position.y = 0.0;
00233     iMarker.pose.position.z = 0.0;
00234     iMarker.pose.orientation.x = 0.0;
00235     iMarker.pose.orientation.y = 0.0;
00236     iMarker.pose.orientation.z = 0.0;
00237     iMarker.pose.orientation.w = 1.0;
00238   }
00239   iMarker.scale = .2;
00240 
00241   iMarker.name = "jaco_hand_marker";
00242   iMarker.description = "JACO Hand Control";
00243 
00244   //make a sphere control to represent the end effector position
00245   visualization_msgs::Marker sphereMarker;
00246   sphereMarker.type = visualization_msgs::Marker::SPHERE;
00247   sphereMarker.scale.x = iMarker.scale * 1;
00248   sphereMarker.scale.y = iMarker.scale * 1;
00249   sphereMarker.scale.z = iMarker.scale * 1;
00250   sphereMarker.color.r = .5;
00251   sphereMarker.color.g = .5;
00252   sphereMarker.color.b = .5;
00253   sphereMarker.color.a = 0.0;
00254   visualization_msgs::InteractiveMarkerControl sphereControl;
00255   sphereControl.markers.push_back(sphereMarker);
00256   sphereControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00257   sphereControl.name = "jaco_hand_origin_marker";
00258   iMarker.controls.push_back(sphereControl);
00259 
00260   //add 6-DOF controls
00261   visualization_msgs::InteractiveMarkerControl control;
00262 
00263   control.orientation.w = 1;
00264   control.orientation.x = 1;
00265   control.orientation.y = 0;
00266   control.orientation.z = 0;
00267   control.name = "rotate_x";
00268   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00269   iMarker.controls.push_back(control);
00270   control.name = "move_x";
00271   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00272   iMarker.controls.push_back(control);
00273 
00274   control.orientation.w = 1;
00275   control.orientation.x = 0;
00276   control.orientation.y = 1;
00277   control.orientation.z = 0;
00278   control.name = "rotate_y";
00279   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00280   iMarker.controls.push_back(control);
00281   control.name = "move_y";
00282   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00283   iMarker.controls.push_back(control);
00284 
00285   control.orientation.w = 1;
00286   control.orientation.x = 0;
00287   control.orientation.y = 0;
00288   control.orientation.z = 1;
00289   control.name = "rotate_z";
00290   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00291   iMarker.controls.push_back(control);
00292   control.name = "move_z";
00293   control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00294   iMarker.controls.push_back(control);
00295 
00296   //menu
00297   interactive_markers::MenuHandler::EntryHandle fingersSubMenuHandle = menuHandler.insert("Gripper");
00298   menuHandler.insert(fingersSubMenuHandle, "Close",
00299                      boost::bind(&CarlInteractiveManipulation::processHandMarkerFeedback, this, _1));
00300   menuHandler.insert(fingersSubMenuHandle, "Open",
00301                      boost::bind(&CarlInteractiveManipulation::processHandMarkerFeedback, this, _1));
00302   menuHandler.insert("Ready Arm", boost::bind(&CarlInteractiveManipulation::processHandMarkerFeedback, this, _1));
00303   menuHandler.insert("Retract Arm", boost::bind(&CarlInteractiveManipulation::processHandMarkerFeedback, this, _1));
00304 
00305   visualization_msgs::InteractiveMarkerControl menuControl;
00306   menuControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::MENU;
00307   menuControl.name = "jaco_hand_menu";
00308   iMarker.controls.push_back(menuControl);
00309 
00310   imServer->insert(iMarker);
00311   imServer->setCallback(iMarker.name, boost::bind(&CarlInteractiveManipulation::processHandMarkerFeedback, this, _1));
00312 
00313   menuHandler.apply(*imServer, iMarker.name);
00314 }
00315 
00316 void CarlInteractiveManipulation::processPickupMarkerFeedback(
00317     const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00318 {
00319   if (feedback->event_type == visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT)
00320   {
00321     boost::recursive_mutex::scoped_lock lock(api_mutex); //lock for segmented objects
00322 
00323     rail_manipulation_msgs::PickupGoal pickupGoal;
00324     pickupGoal.lift = true;
00325     pickupGoal.verify = false;
00326     int objectIndex = atoi(feedback->marker_name.substr(6).c_str());
00327     for (unsigned int i = 0; i < segmentedObjectList.objects[objectIndex].grasps.size(); i ++)
00328     {
00329       ROS_INFO("ATTEMPTING PICKUP WITH GRASP %d", i);
00330       pickupGoal.pose = segmentedObjectList.objects[objectIndex].grasps[i].grasp_pose;
00331       acPickup.sendGoal(pickupGoal);
00332       acPickup.waitForResult(ros::Duration(30.0));
00333 
00334       rail_manipulation_msgs::PickupResultConstPtr pickupResult = acPickup.getResult();
00335       if (!pickupResult->success)
00336       {
00337         ROS_INFO("PICKUP FAILED, moving on to a new grasp...");
00338         continue;
00339       }
00340 
00341       ROS_INFO("PICKUP SUCCEEDED!");
00342 
00343       removeObjectMarker(objectIndex);
00344       break;
00345     }
00346     ROS_INFO("FINISHED ATTEMPTING PICKUPS");
00347 
00348     imServer->applyChanges();
00349   }
00350 }
00351 
00352 void CarlInteractiveManipulation::processRemoveMarkerFeedback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00353 {
00354   if (feedback->event_type == visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT)
00355   {
00356     boost::recursive_mutex::scoped_lock lock(api_mutex); //lock for object list
00357 
00358     if (!removeObjectMarker(atoi(feedback->marker_name.substr(6).c_str())))
00359       return;
00360 
00361     imServer->applyChanges();
00362   }
00363 }
00364 
00365 bool CarlInteractiveManipulation::removeObjectMarker(int index)
00366 {
00367   rail_pick_and_place_msgs::RemoveObject::Request req;
00368   rail_pick_and_place_msgs::RemoveObject::Response res;
00369   req.index = index;
00370   if (!removeObjectClient.call(req, res))
00371   {
00372     ROS_INFO("Could not call remove object service.");
00373     return false;
00374   }
00375   return true;
00376 }
00377 
00378 void CarlInteractiveManipulation::processHandMarkerFeedback(
00379     const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00380 {
00381   switch (feedback->event_type)
00382   {
00383   //Send a stop command so that when the marker is released the arm stops moving
00384   case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
00385     if (feedback->marker_name.compare("jaco_hand_marker") == 0)
00386     {
00387       lockPose = true;
00388       movingArm = false;
00389       if (disableArmMarkerCommands)
00390         disableArmMarkerCommands = false;
00391       sendStopCommand();
00392     }
00393     break;
00394 
00395     //Menu actions
00396   case visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT:
00397     if (feedback->marker_name.compare("jaco_hand_marker") == 0)
00398     {
00399       if (feedback->menu_entry_id == 2) //grasp requested
00400       {
00401         rail_manipulation_msgs::GripperGoal gripperGoal;
00402         gripperGoal.close = true;
00403         acGripper.sendGoal(gripperGoal);
00404       }
00405       else if (feedback->menu_entry_id == 3)    //release requested
00406       {
00407         rail_manipulation_msgs::GripperGoal gripperGoal;
00408         gripperGoal.close = false;
00409         acGripper.sendGoal(gripperGoal);
00410 
00411         std_srvs::Empty emptySrv;
00412         if (!detachObjectsClient.call(emptySrv))
00413         {
00414           ROS_INFO("Couldn't call detach objects service.");
00415         }
00416       }
00417       else if (feedback->menu_entry_id == 4)  //home requested
00418       {
00419         acGripper.cancelAllGoals();
00420         rail_manipulation_msgs::ArmGoal homeGoal;
00421         homeGoal.action = rail_manipulation_msgs::ArmGoal::READY;
00422         acArm.sendGoal(homeGoal);
00423         acArm.waitForResult(ros::Duration(10.0));
00424       }
00425       else if (feedback->menu_entry_id == 5)
00426       {
00427         acGripper.cancelAllGoals();
00428         rail_manipulation_msgs::ArmGoal homeGoal;
00429         homeGoal.action = rail_manipulation_msgs::ArmGoal::RETRACT;
00430         acArm.sendGoal(homeGoal);
00431         acArm.waitForResult(ros::Duration(15.0));
00432       }
00433     }
00434     break;
00435 
00436     //Send movement commands to the arm to follow the pose marker
00437   case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
00438     if (feedback->marker_name.compare("jaco_hand_marker") == 0
00439         && feedback->control_name.compare("jaco_hand_origin_marker") != 0)
00440     {
00441       if (!(lockPose || disableArmMarkerCommands))
00442       {
00443         if (isArmRetracted())
00444         {
00445           if (ros::Time::now().toSec() - lastRetractedFeedback.toSec() >= 5.0)
00446           {
00447             carl_safety::Error armRetractedError;
00448             armRetractedError.message = "Arm is retracted. Ready the arm before moving it.";
00449             armRetractedError.severity = 0;
00450             armRetractedError.resolved = false;
00451             safetyErrorPublisher.publish(armRetractedError);
00452           }
00453         }
00454 
00455         movingArm = true;
00456 
00457         acGripper.cancelAllGoals();
00458 
00459         //convert pose for compatibility with JACO API
00460         wpi_jaco_msgs::QuaternionToEuler qeSrv;
00461         qeSrv.request.orientation = feedback->pose.orientation;
00462         if (qeClient.call(qeSrv))
00463         {
00464           wpi_jaco_msgs::CartesianCommand cmd;
00465           cmd.position = true;
00466           cmd.armCommand = true;
00467           cmd.fingerCommand = false;
00468           cmd.repeat = false;
00469           cmd.arm.linear.x = feedback->pose.position.x;
00470           cmd.arm.linear.y = feedback->pose.position.y;
00471           cmd.arm.linear.z = feedback->pose.position.z;
00472           cmd.arm.angular.x = qeSrv.response.roll;
00473           cmd.arm.angular.y = qeSrv.response.pitch;
00474           cmd.arm.angular.z = qeSrv.response.yaw;
00475 
00476           cartesianCmd.publish(cmd);
00477 
00478           markerPose[0] = feedback->pose.position.x;
00479           markerPose[1] = feedback->pose.position.y;
00480           markerPose[2] = feedback->pose.position.z;
00481           markerPose[3] = qeSrv.response.roll;
00482           markerPose[4] = qeSrv.response.pitch;
00483           markerPose[5] = qeSrv.response.yaw;
00484         }
00485         else
00486           ROS_INFO("Quaternion to Euler conversion service failed, could not send pose update");
00487       }
00488     }
00489     break;
00490 
00491     //Mouse down events
00492   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
00493     lockPose = false;
00494     break;
00495 
00496     //As with mouse clicked, send a stop command when the mouse is released on the marker
00497   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
00498     if (feedback->marker_name.compare("jaco_hand_marker") == 0)
00499     {
00500       lockPose = true;
00501       movingArm = false;
00502       if (disableArmMarkerCommands)
00503         disableArmMarkerCommands = false;
00504       sendStopCommand();
00505     }
00506     break;
00507   }
00508 
00509   //Update interactive marker server
00510   imServer->applyChanges();
00511 }
00512 
00513 void CarlInteractiveManipulation::sendStopCommand()
00514 {
00515   wpi_jaco_msgs::CartesianCommand cmd;
00516   cmd.position = false;
00517   cmd.armCommand = true;
00518   cmd.fingerCommand = false;
00519   cmd.repeat = true;
00520   cmd.arm.linear.x = 0.0;
00521   cmd.arm.linear.y = 0.0;
00522   cmd.arm.linear.z = 0.0;
00523   cmd.arm.angular.x = 0.0;
00524   cmd.arm.angular.y = 0.0;
00525   cmd.arm.angular.z = 0.0;
00526   cartesianCmd.publish(cmd);
00527 
00528   std_srvs::Empty srv;
00529   if (!eraseTrajectoriesClient.call(srv))
00530   {
00531     ROS_INFO("Could not call erase trajectories service...");
00532   }
00533 }
00534 
00535 void CarlInteractiveManipulation::updateMarkerPosition()
00536 {
00537   wpi_jaco_msgs::JacoFK fkSrv;
00538   for (unsigned int i = 0; i < 6; i++)
00539   {
00540     fkSrv.request.joints.push_back(joints.at(i));
00541   }
00542 
00543   if (jacoFkClient.call(fkSrv))
00544   {
00545     imServer->setPose("jaco_hand_marker", fkSrv.response.handPose.pose);
00546     imServer->applyChanges();
00547   }
00548   else
00549   {
00550     ROS_INFO("Failed to call forward kinematics service");
00551   }
00552 }
00553 
00554 void CarlInteractiveManipulation::armCollisionRecovery()
00555 {
00556   //check if recovery is already in progress
00557   if (disableArmMarkerCommands)
00558     return;
00559 
00560   wpi_jaco_msgs::GetCartesianPosition posSrv;
00561   if (!armCartesianPositionClient.call(posSrv))
00562   {
00563     ROS_INFO("Could not call arm Cartesian position service.");
00564     return;
00565   }
00566   wpi_jaco_msgs::CartesianCommand cmd;
00567   cmd.armCommand = true;
00568   cmd.fingerCommand = false;
00569   cmd.position = false;
00570   cmd.repeat = true;
00571   cmd.arm.linear.x = 0;
00572   cmd.arm.linear.y = 0;
00573   cmd.arm.linear.z = 0;
00574   cmd.arm.angular.x = 0;
00575   cmd.arm.angular.y = 0;
00576   cmd.arm.angular.z = 0;
00577 
00578   vector<float> error;
00579   error.resize(3);
00580   error[0] = posSrv.response.pos.linear.x - markerPose[0];
00581   error[1] = posSrv.response.pos.linear.y - markerPose[1];
00582   error[2] = posSrv.response.pos.linear.z - markerPose[2];
00583   /* Currently using translation only, as the rotations don't seem to move the arm into very dangerous positions
00584   error[3] = posSrv.response.pos.angular.x - markerPose[3];
00585   error[4] = posSrv.response.pos.angular.y - markerPose[4];
00586   error[5] = posSrv.response.pos.angular.z - markerPose[5];
00587   for (unsigned int i = 3; i <= 5; i ++)
00588   {
00589     if (error[i] > M_PI)
00590       error[i] -= M_PI;
00591     else if (error[i] < -M_PI)
00592       error[i] += M_PI;
00593   }
00594   */
00595   float maxError;
00596   if (fabs(error[0]) > fabs(error[1]) && fabs(error[0]) > fabs(error[2]))
00597   {
00598     if (error[0] < 0)
00599       cmd.arm.linear.x = -.175;
00600     else
00601       cmd.arm.linear.x = .175;
00602 
00603     maxError = error[0];
00604   }
00605   else if (fabs(error[1]) > fabs(error[0]) && fabs(error[1]) > fabs(error[2]))
00606   {
00607     if (error[1] < 0)
00608       cmd.arm.linear.y = -.175;
00609     else
00610       cmd.arm.linear.y = .175;
00611     maxError = error[1];
00612   }
00613   else
00614   {
00615     if (error[2] < 0)
00616       cmd.arm.linear.z = -.175;
00617     else
00618       cmd.arm.linear.z = .175;
00619     maxError = error[2];
00620   }
00621 
00622   //ignore if error is less than 1 cm to prevent accidental clicks from starting a recovery behavior
00623   if (fabs(maxError) < .01)
00624   {
00625     return;
00626   }
00627 
00628   disableArmMarkerCommands = true;
00629 
00630   //feedback
00631   carl_safety::Error armCollisionError;
00632   armCollisionError.message = "Arm in dangerous collision, moving to a safer position...";
00633   armCollisionError.severity = 1;
00634   armCollisionError.resolved = false;
00635   safetyErrorPublisher.publish(armCollisionError);
00636 
00637   wpi_jaco_msgs::EStop eStopSrv;
00638   eStopSrv.request.enableEStop = true;
00639   if (!armEStopClient.call(eStopSrv))
00640   {
00641     ROS_INFO("Could not call arm EStop service.");
00642     return;
00643   }
00644 
00645   eStopSrv.request.enableEStop = false;
00646   if (!armEStopClient.call(eStopSrv))
00647   {
00648     ROS_INFO("Could not call arm EStop service.");
00649     return;
00650   }
00651 
00652   ros::Rate loopRate(60);
00653   for (unsigned int i = 0; i < 60; i ++)
00654   {
00655     cartesianCmd.publish(cmd);
00656     loopRate.sleep();
00657   }
00658 
00659   //feedback
00660   carl_safety::Error armCollisionErrorResolved;
00661   armCollisionErrorResolved.message = "Arm recovered.";
00662   armCollisionErrorResolved.severity = 1;
00663   armCollisionErrorResolved.resolved = true;
00664   safetyErrorPublisher.publish(armCollisionErrorResolved);
00665 }
00666 
00667 bool CarlInteractiveManipulation::isArmRetracted()
00668 {
00669   float dstFromRetract = 0;
00670 
00671   //get joint positions
00672   wpi_jaco_msgs::GetAngularPosition::Request req;
00673   wpi_jaco_msgs::GetAngularPosition::Response res;
00674   if(!armAngularPositionClient.call(req, res))
00675   {
00676     ROS_INFO("Could not call Jaco joint position service.");
00677     return false;
00678   }
00679 
00680   for (unsigned int i = 0; i < 6; i ++)
00681   {
00682     dstFromRetract += fabs(retractPos[i] - res.pos[i]);
00683   }
00684 
00685   if (dstFromRetract > 0.175)
00686     return false;
00687   return true;
00688 }
00689 
00690 int main(int argc, char **argv)
00691 {
00692   ros::init(argc, argv, "jaco_interactive_manipulation");
00693 
00694   CarlInteractiveManipulation cim;
00695 
00696   ros::Rate loop_rate(30);
00697   while (ros::ok())
00698   {
00699     cim.updateMarkerPosition();
00700     ros::spinOnce();
00701     loop_rate.sleep();
00702   }
00703 }
00704 


carl_interactive_manipulation
Author(s): David Kent , Peter Mitrano
autogenerated on Thu Jun 6 2019 21:09:51