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
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
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
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
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
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
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
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);
00101
00102
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
00132 objectControl.always_visible = true;
00133 objectControl.markers.resize(1);
00134
00135 objectControl.markers[0] = objectList->objects[i].marker;
00136 objectMarker.controls.push_back(objectControl);
00137
00138
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
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);
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
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
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
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
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);
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);
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
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
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)
00400 {
00401 rail_manipulation_msgs::GripperGoal gripperGoal;
00402 gripperGoal.close = true;
00403 acGripper.sendGoal(gripperGoal);
00404 }
00405 else if (feedback->menu_entry_id == 3)
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)
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
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
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
00492 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
00493 lockPose = false;
00494 break;
00495
00496
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
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
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
00584
00585
00586
00587
00588
00589
00590
00591
00592
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
00623 if (fabs(maxError) < .01)
00624 {
00625 return;
00626 }
00627
00628 disableArmMarkerCommands = true;
00629
00630
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
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
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