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
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
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
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
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
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
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
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
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
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)
00174 {
00175 rail_manipulation_msgs::GripperGoal gripperGoal;
00176 gripperGoal.close = true;
00177 acGripper.sendGoal(gripperGoal);
00178 }
00179 else if (feedback->menu_entry_id == 3)
00180 {
00181 rail_manipulation_msgs::GripperGoal gripperGoal;
00182 gripperGoal.close = false;
00183 acGripper.sendGoal(gripperGoal);
00184 }
00185 else if (feedback->menu_entry_id == 4)
00186 {
00187 rail_manipulation_msgs::LiftGoal liftGoal;
00188 acLift.sendGoal(liftGoal);
00189 }
00190 else if (feedback->menu_entry_id == 5)
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
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
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
00258 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
00259 lockPose = false;
00260 break;
00261
00262
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
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