Go to the documentation of this file.00001 #include <remote_manipulation_markers/ConstrainedPositioning.h>
00002
00003 using namespace std;
00004
00005 ConstrainedPositioning::ConstrainedPositioning() :
00006 pnh("~"), specifiedGraspServer(pnh, "execute_grasp", boost::bind(&ConstrainedPositioning::executeGraspCallback, this, _1), false)
00007 {
00008
00009 string graspTopic;
00010 pnh.param<string>("grasp_topic", graspTopic, "grasp");
00011
00012
00013 markerPosePublisher = pnh.advertise<geometry_msgs::PoseStamped>("gripper_marker_pose", 1);
00014
00015
00016 clearGripperMarkerServer = pnh.advertiseService("clear_gripper_marker", &ConstrainedPositioning::clearGripperMarkerCallback, this);
00017 clearFullMarkerServer = pnh.advertiseService("clear_full_marker", &ConstrainedPositioning::clearFullMarkerCallback, this);
00018 createSphereServer = pnh.advertiseService("create_sphere", &ConstrainedPositioning::createSphereMarkerCallback, this);
00019
00020
00021 graspClient = new actionlib::SimpleActionClient<rail_manipulation_msgs::PickupAction>(graspTopic);
00022
00023 imServer.reset(
00024 new interactive_markers::InteractiveMarkerServer("constrained_positioning", "constrained_positioning", false));
00025
00026 ros::Duration(0.1).sleep();
00027
00028 imServer->applyChanges();
00029
00030 specifiedGraspServer.start();
00031 }
00032
00033 ConstrainedPositioning::~ConstrainedPositioning()
00034 {
00035 delete graspClient;
00036 }
00037
00038 bool ConstrainedPositioning::createSphereMarkerCallback(remote_manipulation_markers::CreateSphere::Request &req, remote_manipulation_markers::CreateSphere::Response &res)
00039 {
00040 boost::recursive_mutex::scoped_lock lock(graspMutex);
00041
00042 imServer->clear();
00043
00044 visualization_msgs::InteractiveMarker sphere;
00045 sphere.header.frame_id = req.point.header.frame_id;
00046 sphere.pose.position.x = req.point.point.x;
00047 sphere.pose.position.y = req.point.point.y;
00048 sphere.pose.position.z = req.point.point.z;
00049 sphere.pose.orientation.w = 1.0;
00050
00051 sphere.scale = 1.0;
00052
00053 sphere.name = "cp_sphere";
00054 sphere.description = "Specify a grasp";
00055
00056 visualization_msgs::Marker sphereMarker;
00057 sphereMarker.ns = "cp";
00058 sphereMarker.id = 0;
00059 sphereMarker.type = visualization_msgs::Marker::SPHERE;
00060
00061 sphereMarker.pose.orientation.w = 1.0;
00062 sphereMarker.scale.x = 0.3;
00063 sphereMarker.scale.y = 0.3;
00064 sphereMarker.scale.z = 0.3;
00065 sphereMarker.color.r = 0.8;
00066 sphereMarker.color.g = 0.3;
00067 sphereMarker.color.b = 0.1;
00068 sphereMarker.color.a = 0.5;
00069
00070 visualization_msgs::InteractiveMarkerControl sphereMarkerControl;
00071 sphereMarkerControl.name = "cp_sphere_control";
00072 sphereMarkerControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00073 sphereMarkerControl.always_visible = true;
00074 sphereMarkerControl.description = "Click to set an approach angle";
00075 sphereMarkerControl.markers.push_back(sphereMarker);
00076
00077 visualization_msgs::Marker centerMarker;
00078 centerMarker.ns = "cp";
00079 centerMarker.id = 1;
00080 centerMarker.type = visualization_msgs::Marker::SPHERE;
00081 centerMarker.pose.orientation.w = 1.0;
00082 centerMarker.scale.x = 0.02;
00083 centerMarker.scale.y = 0.02;
00084 centerMarker.scale.z = 0.02;
00085 centerMarker.color.r = 0.0;
00086 centerMarker.color.g = 0.0;
00087 centerMarker.color.b = 1.0;
00088 centerMarker.color.a = 1.0;
00089
00090 visualization_msgs::InteractiveMarkerControl centerMarkerControl;
00091 centerMarkerControl.name = "cp_center_control";
00092 centerMarkerControl.interaction_mode = visualization_msgs::InteractiveMarkerControl::NONE;
00093 centerMarkerControl.always_visible = true;
00094 centerMarkerControl.description = "";
00095 centerMarkerControl.markers.push_back(centerMarker);
00096
00097 sphere.controls.push_back(sphereMarkerControl);
00098 sphere.controls.push_back(centerMarkerControl);
00099
00100 imServer->insert(sphere);
00101 imServer->setCallback(sphere.name, boost::bind(&ConstrainedPositioning::processMarkerFeedback, this, _1));
00102 imServer->applyChanges();
00103
00104 return true;
00105 }
00106
00107 void ConstrainedPositioning::processMarkerFeedback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00108 {
00109 boost::recursive_mutex::scoped_lock lock(graspMutex);
00110 if (feedback->control_name == "cp_sphere_control" && feedback->event_type == visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK)
00111 {
00112 if (feedback->mouse_point_valid)
00113 {
00114 visualization_msgs::InteractiveMarker cpSphere;
00115 imServer->get("cp_sphere", cpSphere);
00116 visualization_msgs::Marker sphere = cpSphere.controls[0].markers[0];
00117 double roll = 0;
00118 double pitch = -asin((cpSphere.pose.position.z - feedback->mouse_point.z)/sqrt(pow(feedback->mouse_point.x - cpSphere.pose.position.x, 2) + pow(feedback->mouse_point.y - cpSphere.pose.position.y, 2) + pow(feedback->mouse_point.z - cpSphere.pose.position.z, 2)));
00119 double yaw = atan2(cpSphere.pose.position.y - feedback->mouse_point.y, cpSphere.pose.position.x - feedback->mouse_point.x);
00120
00121
00122
00123 geometry_msgs::QuaternionStamped orientation;
00124 orientation.quaternion = tf::createQuaternionMsgFromRollPitchYaw(roll, pitch, yaw);
00125 orientation.header.frame_id = cpSphere.header.frame_id;
00126
00127 visualization_msgs::InteractiveMarker gripperMarker;
00128 geometry_msgs::PoseStamped pose;
00129 pose.header.frame_id = orientation.header.frame_id;
00130 pose.pose.position = feedback->mouse_point;
00131 pose.pose.orientation = orientation.quaternion;
00132 if (imServer->get("gripper", gripperMarker))
00133 {
00134
00135 imServer->setPose("gripper", pose.pose, pose.header);
00136 }
00137 else
00138 {
00139
00140 gripperMarker = Common::makeGripperMarker(pose);
00141
00142
00143 visualization_msgs::InteractiveMarkerControl control;
00144
00145 control.orientation.w = 1;
00146 control.orientation.x = 1;
00147 control.orientation.y = 0;
00148 control.orientation.z = 0;
00149 control.name = "rotate_x";
00150 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00151 gripperMarker.controls.push_back(control);
00152
00153 control.name = "move_z";
00154 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00155 gripperMarker.controls.push_back(control);
00156
00157 imServer->insert(gripperMarker);
00158 }
00159 imServer->applyChanges();
00160 }
00161 else
00162 {
00163 ROS_INFO("Invalid mouse point");
00164 }
00165 }
00166 }
00167
00168 void ConstrainedPositioning::executeGraspCallback(const remote_manipulation_markers::SpecifiedGraspGoalConstPtr &goal)
00169 {
00170 boost::recursive_mutex::scoped_lock lock(graspMutex);
00171
00172 remote_manipulation_markers::SpecifiedGraspFeedback feedback;
00173 remote_manipulation_markers::SpecifiedGraspResult result;
00174
00175 feedback.message = "Moving arm to your set position...";
00176 specifiedGraspServer.publishFeedback(feedback);
00177
00178 visualization_msgs::InteractiveMarker poseMarker;
00179 if (!imServer->get("gripper", poseMarker))
00180 {
00181 feedback.message = "Please specify a grasp first. See the instructions pane for details.";
00182 specifiedGraspServer.publishFeedback(feedback);
00183 result.success = false;
00184 result.executionSuccess = false;
00185 specifiedGraspServer.setSucceeded(result);
00186 return;
00187 }
00188
00189 rail_manipulation_msgs::PickupGoal graspGoal;
00190 graspGoal.pose.header = poseMarker.header;
00191 graspGoal.pose.pose = poseMarker.pose;
00192 graspGoal.lift = false;
00193 graspGoal.verify = false;
00194 graspClient->sendGoal(graspGoal);
00195 graspClient->waitForResult(ros::Duration(30.0));
00196 rail_manipulation_msgs::PickupResultConstPtr graspResult = graspClient->getResult();
00197 result.success = graspResult->success;
00198 result.executionSuccess = graspResult->executionSuccess;
00199 if (!graspResult->executionSuccess)
00200 {
00201 ROS_INFO("Grasp failed!");
00202 feedback.message = "Failed to plan to your grasp. Try a different start or end pose, and watch out for collisions.";
00203 }
00204 else
00205 {
00206 ROS_INFO("Grasp succeeded.");
00207 feedback.message = "Success!";
00208 }
00209 specifiedGraspServer.publishFeedback(feedback);
00210 specifiedGraspServer.setSucceeded(result);
00211 }
00212
00213 bool ConstrainedPositioning::clearGripperMarkerCallback(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
00214 {
00215 boost::recursive_mutex::scoped_lock lock(graspMutex);
00216 imServer->erase("gripper");
00217 imServer->applyChanges();
00218
00219 return true;
00220 }
00221
00222 bool ConstrainedPositioning::clearFullMarkerCallback(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
00223 {
00224 boost::recursive_mutex::scoped_lock lock(graspMutex);
00225 imServer->clear();
00226 imServer->applyChanges();
00227
00228 return true;
00229 }
00230
00231 void ConstrainedPositioning::publishMarkerPose()
00232 {
00233 visualization_msgs::InteractiveMarker poseMarker;
00234 if (imServer->get("gripper", poseMarker))
00235 {
00236 geometry_msgs::PoseStamped pose;
00237 pose.header = poseMarker.header;
00238 pose.pose = poseMarker.pose;
00239
00240 markerPosePublisher.publish(pose);
00241 }
00242 }
00243
00244 int main(int argc, char **argv)
00245 {
00246 ros::init(argc, argv, "constrained_positioning");
00247
00248 ConstrainedPositioning cp;
00249
00250 ros::Rate loopRate(30);
00251 while (ros::ok())
00252 {
00253 cp.publishMarkerPose();
00254 ros::spinOnce();
00255 loopRate.sleep();
00256 }
00257 }