00001
00002
00003
00004
00005
00006
00007
00008 #include <object_manipulation_tools/robot_navigators/RobotNavigator.h>
00009 #include <boost/foreach.hpp>
00010 #include <object_manipulation_tools/manipulation_utils/Utilities.h>
00011
00012
00013
00014
00015 std::string RobotNavigator::NODE_NAME = "robot_pick_place";
00016 std::string RobotNavigator::NAVIGATOR_NAMESPACE = "navigator";
00017 std::string RobotNavigator::MARKER_ARM_LINK = "arm_links";
00018 std::string RobotNavigator::MARKER_ATTACHED_OBJECT = "attached_object";
00019 std::string RobotNavigator::VISUALIZATION_TOPIC = "visualization_markers";
00020
00021 const tf::Transform RobotNavigator::PLACE_RECTIFICATION_TF = tf::Transform(
00022 tf::Quaternion(tf::Vector3(1.0f,0.0f,0.0f),M_PI),tf::Vector3(0.0f,0.0f,0.0f));
00023
00024
00025 const double GRAP_ACTION_TIMEOUT = 4.0f;
00026
00027 void RobotNavigator::fetchParameters(std::string nameSpace)
00028 {
00029 ros::NodeHandle nh;
00030 using namespace RobotNavigatorParameters;
00031
00032 ros::param::param(nameSpace + "/" + PARAM_NAME_ARM_GROUP,arm_group_name_,DEFAULT_ARM_GROUP);
00033 ros::param::param(nameSpace + "/" + PARAM_NAME_GRIPPER_GROUP,gripper_group_name_,DEFAULT_GRIPPER_GROUP);
00034 ros::param::param(nameSpace + "/" + PARAM_NAME_WRIST_LINK,wrist_link_name_,DEFAULT_WRIST_LINK);
00035 ros::param::param(nameSpace + "/" + PARAM_NAME_GRIPPER_LINK,gripper_link_name_,DEFAULT_GRIPPER_LINK);
00036 ros::param::param(nameSpace + "/" + PARAM_NAME_GRASP_ACTION_SERVICE,grasp_action_service_,DEFAULT_GRASP_ACTION_SERVICE );
00037 ros::param::param(nameSpace + "/" + PARAM_NAME_TRAJECTORY_ACTION_SERVICE,trajectory_action_service_,DEFAULT_TRAJECTORY_ACTION_SERVICE);
00038 ros::param::param(nameSpace + "/" + PARAM_NAME_PATH_PLANNER_SERVICE,path_planner_service_,DEFAULT_PATH_PLANNER_SERVICE);
00039 ros::param::param(nameSpace + "/" + PARAM_NAME_TRAJECTORY_FILTER_SERVICE,trajectory_filter_service_,DEFAULT_TRAJECTORY_FILTER_SERVICE);
00040 ros::param::param(nameSpace + "/" + PARAM_NAME_SEGMENTATION_SERVICE,segmentation_service_,DEFAULT_SEGMENTATION_SERVICE);
00041 ros::param::param(nameSpace + "/" + PARAM_NAME_RECOGNITION_SERVICE,recognition_service_,DEFAULT_RECOGNITION_SERVICE);
00042 ros::param::param(nameSpace + "/" + PARAM_NAME_GRASP_PLANNING_SERVICE,grasp_planning_service_,DEFAULT_GRASP_PLANNING_SERVICE);
00043 ros::param::param(nameSpace + "/" + PARAM_NAME_MESH_DATABASE_SERVICE,mesh_database_service_,DEFAULT_MESH_DATABASE_SERVICE);
00044 ros::param::param(nameSpace + "/" + PARAM_NAME_MODEL_DATABASE_SERVICE,model_database_service_,DEFAULT_MODEL_DATABASE_SERVICE);
00045 ros::param::param(nameSpace + "/" + PARAM_NAME_PLANNING_SCENE_SERVICE,planning_scene_service_,DEFAULT_PLANNING_SCENE_SERVICE);
00046 ros::param::param(nameSpace + "/" + PARAM_NAME_IK_PLUGING,ik_plugin_name_,DEFAULT_IK_PLUGING);
00047 ros::param::param(nameSpace + "/" + PARAM_NAME_JOINT_STATES_TOPIC,joint_states_topic_,DEFAULT_JOINT_STATES_TOPIC);
00048
00049 ros::param::param(nameSpace + "/" + PARAM_PICK_APPROACH_DISTANCE,pick_approach_distance_,DF_PICK_APPROACH_DISTANCE);
00050 ros::param::param(nameSpace + "/" + PARAM_PLACE_APPROACH_DISTANCE,place_approach_distance_,DF_PLACE_APPROACH_DISTANCE);
00051 ros::param::param(nameSpace + "/" + PARAM_PLACE_RETREAT_DISTANCE,place_retreat_distance_,DF_PLACE_RETREAT_DISTANCE);
00052 }
00053
00054 RobotNavigator::RobotNavigator()
00055 : cm_("robot_description"),
00056 current_robot_state_(NULL),
00057 pick_approach_distance_(RobotNavigatorParameters::DF_PICK_APPROACH_DISTANCE),
00058 place_approach_distance_(RobotNavigatorParameters::DF_PLACE_APPROACH_DISTANCE),
00059 place_retreat_distance_(RobotNavigatorParameters::DF_PLACE_RETREAT_DISTANCE)
00060
00061 {
00062 ros::NodeHandle nh;
00063
00064
00065 NODE_NAME = ros::this_node::getName();
00066 NAVIGATOR_NAMESPACE = NODE_NAME + "/" + NAVIGATOR_NAMESPACE;
00067 VISUALIZATION_TOPIC = NODE_NAME + "/" + VISUALIZATION_TOPIC;
00068 }
00069
00070 RobotNavigator::~RobotNavigator()
00071 {
00072
00073 }
00074
00075 void RobotNavigator::setup()
00076 {
00077 ros::NodeHandle nh;
00078 std::string nodeName = ros::this_node::getName();
00079
00080 ROS_INFO_STREAM(NODE_NAME<<": Loading ros parameters");
00081
00082
00083 fetchParameters(NAVIGATOR_NAMESPACE);
00084
00085 ROS_INFO_STREAM(NODE_NAME<<": Setting up execution Monitors");
00086
00087 {
00088 joint_state_recorder_.reset(new JointStateTrajectoryRecorder(joint_states_topic_));
00089 arm_controller_handler_.reset(new FollowJointTrajectoryControllerHandler(arm_group_name_,trajectory_action_service_));
00090 gripper_controller_handler_.reset(new GraspPoseControllerHandler(gripper_group_name_,grasp_action_service_));
00091
00092 trajectory_execution_monitor_.addTrajectoryRecorder(joint_state_recorder_);
00093 trajectory_execution_monitor_.addTrajectoryControllerHandler(arm_controller_handler_);
00094 trajectory_execution_monitor_.addTrajectoryControllerHandler(gripper_controller_handler_);
00095 }
00096
00097 ROS_INFO_STREAM(NODE_NAME<<": Setting up Service Clients");
00098
00099 {
00100
00101 seg_srv_ = nh.serviceClient<tabletop_object_detector::TabletopSegmentation>(segmentation_service_, true);
00102 rec_srv_ = nh.serviceClient<tabletop_object_detector::TabletopObjectRecognition>(
00103 recognition_service_, true);
00104 object_database_model_mesh_client_ = nh.serviceClient<household_objects_database_msgs::GetModelMesh>(
00105 mesh_database_service_, true);
00106 object_database_model_description_client_ = nh.serviceClient<household_objects_database_msgs::GetModelDescription>(
00107 model_database_service_, true);
00108
00109
00110 grasp_planning_client = nh.serviceClient<object_manipulation_msgs::GraspPlanning>(grasp_planning_service_, false);
00111 planning_service_client_ = nh.serviceClient<arm_navigation_msgs::GetMotionPlan>(path_planner_service_);
00112
00113
00114 trajectory_filter_service_client_ = nh.serviceClient<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>(trajectory_filter_service_);
00115 ROS_INFO_STREAM(NODE_NAME<<": Waiting for trajectory filter service");
00116 trajectory_filter_service_client_.waitForExistence();
00117 ROS_INFO_STREAM(NODE_NAME<<": Trajectory filter service connected");
00118
00119
00120 ROS_INFO_STREAM(NODE_NAME <<": Waiting for " + planning_scene_service_ + " service");
00121 ros::service::waitForService(planning_scene_service_);
00122 set_planning_scene_diff_client_ = nh.serviceClient<arm_navigation_msgs::SetPlanningSceneDiff>(planning_scene_service_);
00123 }
00124
00125
00126
00127 ROS_INFO_STREAM(NODE_NAME << ": Setting up Service Action Clients");
00128 {
00129 grasp_exec_action_client_ =
00130 boost::make_shared< GraspActionServerClient >(grasp_action_service_,true);
00131 while(!grasp_exec_action_client_->waitForServer(ros::Duration(0.5)))
00132 {
00133 ROS_INFO_STREAM(NODE_NAME << "Waiting for action service "<< grasp_action_service_);
00134 }
00135 ROS_INFO_STREAM(NODE_NAME<<" : Connected to action service "<<grasp_action_service_);
00136 }
00137
00138 ROS_INFO_STREAM(NODE_NAME<<": Setting up ros publishers");
00139 {
00140
00141 marker_publisher_ = nh.advertise<visualization_msgs::Marker> (VISUALIZATION_TOPIC, 128);
00142 attached_object_publisher_ = nh.advertise<arm_navigation_msgs::AttachedCollisionObject> ("attached_collision_object_alternate", 1);
00143
00144
00145 marker_pub_timer_ = nh.createTimer(ros::Duration(0.4f),&RobotNavigator::callbackPublishMarkers,this);
00146
00147 ROS_INFO_STREAM(NODE_NAME<<": Setting up dynamic libraries");
00148
00149
00150 grasp_tester_ = GraspTesterPtr(new GraspSequenceValidator(&cm_, ik_plugin_name_));
00151 place_tester_ = PlaceSequencePtr(new PlaceSequenceValidator(&cm_, ik_plugin_name_));
00152
00153 trajectories_finished_function_ = boost::bind(&RobotNavigator::trajectoryFinishedCallback, this, true,_1);
00154 grasp_action_finished_function_ = boost::bind(&RobotNavigator::trajectoryFinishedCallback, this, false,_1);
00155 ROS_INFO_STREAM(NODE_NAME<<": Finished setup");
00156 }
00157
00158 ROS_INFO_STREAM(NODE_NAME<<" Setting up grasp planning data");
00159 {
00160
00161 grasp_pickup_goal_.arm_name = arm_group_name_;
00162 grasp_pickup_goal_.lift.direction.header.frame_id = cm_.getWorldFrameId();
00163 grasp_pickup_goal_.lift.direction.vector.z = 1.0;
00164 grasp_pickup_goal_.lift.desired_distance = pick_approach_distance_;
00165 grasp_pickup_goal_.lift.min_distance = pick_approach_distance_;
00166 grasp_pickup_goal_.lift.direction.header.frame_id = cm_.getWorldFrameId();
00167 grasp_pickup_goal_.allow_gripper_support_collision = true;
00168 grasp_pickup_goal_.collision_support_surface_name = "table";
00169
00170
00171 grasp_place_goal_.arm_name = arm_group_name_;
00172 grasp_place_goal_.desired_retreat_distance = place_retreat_distance_;
00173 grasp_place_goal_.min_retreat_distance = place_retreat_distance_;
00174 grasp_place_goal_.approach.desired_distance = place_approach_distance_;
00175 grasp_place_goal_.approach.min_distance = place_approach_distance_;
00176 grasp_place_goal_.approach.direction.header.frame_id = cm_.getWorldFrameId();
00177 grasp_place_goal_.approach.direction.vector.x = 0.0;
00178 grasp_place_goal_.approach.direction.vector.y = 0.0;
00179 grasp_place_goal_.approach.direction.vector.z = -1.0;
00180 grasp_place_goal_.allow_gripper_support_collision = true;
00181 grasp_place_goal_.collision_support_surface_name = "table";
00182 grasp_place_goal_.place_padding = .02;
00183 }
00184 }
00185
00186 bool RobotNavigator::trajectoryFinishedCallback(bool storeLastTraj,TrajectoryExecutionDataVector tedv)
00187 {
00188 ROS_INFO_STREAM(NODE_NAME<<":Trajectory execution result flag: "<<tedv.back().result_);
00189
00190
00191 trajectories_succeeded_ = (tedv.back().result_ == SUCCEEDED
00192 || tedv.back().result_ == HANDLER_REPORTS_FAILURE_BUT_OK
00193 || tedv.back().result_ == HANDLER_REPORTS_FAILURE_BUT_CLOSE_ENOUGH);
00194
00195 if(storeLastTraj)
00196 {
00197 if(tedv.size()==0)
00198 {
00199 ROS_ERROR_STREAM(NODE_NAME <<": trajectory finished callback received empty vector");
00200 }
00201 else
00202 {
00203 ROS_INFO_STREAM(NODE_NAME<<": trajectory finished callback storing last trajectory");
00204 last_trajectory_execution_data_vector_ = tedv;
00205 }
00206 }
00207 else
00208 {
00209 ROS_INFO_STREAM(NODE_NAME<<": trajectory finished callback will not store last trajectory");
00210 }
00211
00212
00213 ROS_INFO_STREAM(NODE_NAME<<": Trajectory finished callback notifying all awaiting threads");
00214 execution_completed_.notify_all();
00215 return true;
00216 }
00217
00218 void RobotNavigator::revertPlanningScene()
00219 {
00220
00221 if(current_robot_state_ != NULL)
00222 {
00223 cm_.revertPlanningScene(current_robot_state_);
00224 current_robot_state_ = NULL;
00225 }
00226 last_mpr_id_ = 0;
00227 max_mpr_id_ = 0;
00228 max_trajectory_id_ = 0;
00229 }
00230
00231 std::vector<std::string> RobotNavigator::getJointNames(const std::string& group) {
00232 if(cm_.getKinematicModel()->getModelGroup(group) == NULL) {
00233 std::vector<std::string> names;
00234 return names;
00235 }
00236 return cm_.getKinematicModel()->getModelGroup(group)->getJointModelNames();
00237 }
00238
00239 void RobotNavigator::updateCurrentJointStateToLastTrajectoryPoint(const trajectory_msgs::JointTrajectory& traj)
00240 {
00241 if(traj.points.size() == 0)
00242 {
00243 ROS_ERROR_STREAM(NODE_NAME<<": No points in trajectory for setting current state");
00244 return;
00245 }
00246
00247 std::map<std::string, double> joint_vals;
00248 for(unsigned int i = 0; i < traj.joint_names.size(); i++)
00249 {
00250 joint_vals[traj.joint_names[i]] = traj.points.back().positions[i];
00251 }
00252
00253 current_robot_state_->setKinematicState(joint_vals);
00254 }
00255
00256 bool RobotNavigator::updateChangesToPlanningScene()
00257 {
00258 ros::WallTime start_time = ros::WallTime::now();
00259 arm_navigation_msgs::SetPlanningSceneDiff::Request planning_scene_req;
00260 arm_navigation_msgs::SetPlanningSceneDiff::Response planning_scene_res;
00261
00262 revertPlanningScene();
00263
00264 planning_scene_req.planning_scene_diff = planning_scene_diff_;
00265
00266 ROS_DEBUG_STREAM(NODE_NAME<<": Getting and setting planning scene");
00267
00268 if(!set_planning_scene_diff_client_.call(planning_scene_req, planning_scene_res))
00269 {
00270 ROS_WARN_STREAM(NODE_NAME<<": Can't get planning scene");
00271 return false;
00272 }
00273
00274 current_planning_scene_ = planning_scene_res.planning_scene;
00275 current_robot_state_ = cm_.setPlanningScene(current_planning_scene_);
00276
00277 if(current_robot_state_ == NULL)
00278 {
00279 ROS_WARN_STREAM(NODE_NAME<<": Problems setting robot kinematic state");
00280 return false;
00281 }
00282
00283
00284 current_planning_scene_.robot_state.joint_state.header.stamp = ros::Time(ros::WallTime::now().toSec());
00285 ROS_INFO_STREAM(NODE_NAME<<": Setting took " << (ros::WallTime::now()-start_time).toSec());
00286 planning_scene_duration_ += ros::WallTime::now()-start_time;
00287 return true;
00288 }
00289
00290 bool RobotNavigator::moveArm(const std::string& group_name,const std::vector<double>& joint_positions)
00291 {
00292
00293
00294 ros::WallTime start_time = ros::WallTime::now();
00295 arm_navigation_msgs::GetMotionPlan::Request plan_req;
00296 arm_navigation_msgs::GetMotionPlan::Response plan_res;
00297
00298 plan_req.motion_plan_request.allowed_planning_time = ros::Duration(20.0f);
00299 plan_req.motion_plan_request.group_name = group_name;
00300
00301 planning_environment::convertKinematicStateToRobotState(*current_robot_state_,
00302 ros::Time::now(),
00303 cm_.getWorldFrameId(),
00304 plan_req.motion_plan_request.start_state);
00305
00306 std::vector<std::string> joint_names = getJointNames(group_name);
00307 std::vector<arm_navigation_msgs::JointConstraint>& joint_constraints = plan_req.motion_plan_request.goal_constraints.joint_constraints;
00308
00309 joint_constraints.resize(joint_names.size());
00310 for(unsigned int i = 0; i < joint_names.size(); i++)
00311 {
00312 joint_constraints[i].joint_name = joint_names[i];
00313 joint_constraints[i].position = joint_positions[i];
00314 joint_constraints[i].tolerance_above = 0.2f;
00315 joint_constraints[i].tolerance_below = 0.2f;
00316 }
00317
00318 if(!planning_service_client_.call(plan_req, plan_res))
00319 {
00320 ROS_WARN_STREAM(NODE_NAME<<": Planner service call failed");
00321 return false;
00322 }
00323
00324 if(plan_res.error_code.val != plan_res.error_code.SUCCESS)
00325 {
00326 ROS_WARN_STREAM(NODE_NAME<<": Planner failed, error code:"<<plan_res.error_code.val);
00327 return false;
00328 }
00329
00330 motion_planning_duration_ += ros::WallTime::now()-start_time;
00331 start_time = ros::WallTime::now();
00332
00333 last_mpr_id_ = max_mpr_id_;
00334 max_mpr_id_++;
00335
00336
00337 arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Request filter_req;
00338 arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Response filter_res;
00339
00340 filter_req.trajectory = plan_res.trajectory.joint_trajectory;
00341 filter_req.start_state = plan_req.motion_plan_request.start_state;
00342 filter_req.group_name = group_name;
00343 filter_req.goal_constraints = plan_req.motion_plan_request.goal_constraints;
00344 filter_req.allowed_time = ros::Duration(4.0);
00345
00346 if(!trajectory_filter_service_client_.call(filter_req, filter_res)) {
00347 ROS_WARN_STREAM(NODE_NAME<<": Filter service call failed");
00348 return false;
00349 }
00350
00351 if(filter_res.error_code.val != filter_res.error_code.SUCCESS) {
00352 ROS_WARN_STREAM(NODE_NAME<<": Filter failed");
00353 return false;
00354 }
00355 trajectory_filtering_duration_ += ros::WallTime::now()-start_time;
00356
00357
00358 trajectories_succeeded_ = false;
00359 TrajectoryExecutionRequest ter;
00360 ter.group_name_ = group_name;
00361 ter.controller_name_ = arm_controller_handler_->getControllerName();
00362 ter.trajectory_ = filter_res.trajectory;
00363 ter.test_for_close_enough_ = false;
00364 ter.failure_time_factor_ = 1000;
00365 ter.max_joint_distance_ = .01;
00366
00367 std::vector<TrajectoryExecutionRequest> ter_reqs;
00368 ter_reqs.push_back(ter);
00369
00370 ros::WallTime start_execution = ros::WallTime::now();
00371
00372 ROS_INFO_STREAM("Arm Trajectory in progress");
00373 trajectory_execution_monitor_.executeTrajectories(ter_reqs,trajectories_finished_function_);
00374
00375 boost::unique_lock<boost::mutex> lock(execution_mutex_);
00376 execution_completed_.wait(lock);
00377 execution_duration_ += (ros::WallTime::now()-start_execution);
00378
00379 arm_navigation_msgs::ArmNavigationErrorCodes error_code;
00380 if(trajectories_succeeded_)
00381 {
00382 error_code.val = error_code.SUCCESS;
00383 ROS_INFO_STREAM("Trajectory execution has succeeded");
00384 }
00385 else
00386 {
00387 error_code.val = error_code.PLANNING_FAILED;
00388 ROS_ERROR_STREAM("Trajectory execution has failed");
00389 }
00390
00391 return trajectories_succeeded_;
00392 }
00393
00394 bool RobotNavigator::validateJointTrajectory(trajectory_msgs::JointTrajectory &jt)
00395 {
00396 const ros::Duration timeIncrement(1.0f);
00397 ros::Duration currentTime = timeIncrement ;
00398
00399 for(unsigned int i = 0; i < jt.points.size(); i++)
00400 {
00401 trajectory_msgs::JointTrajectoryPoint &p = jt.points[i];
00402 if(p.positions.size() == 0)
00403 {
00404 return false;
00405 }
00406
00407 if(p.velocities.size() == 0)
00408 {
00409 p.velocities = std::vector<double>(jt.joint_names.size(),0.0f);
00410 }
00411
00412 if(p.accelerations.size() == 0)
00413 {
00414 p.accelerations = std::vector<double>(jt.joint_names.size(),0.0f);
00415 }
00416
00417 p.time_from_start = currentTime;
00418 currentTime = currentTime+ timeIncrement;
00419 }
00420
00421 return true;
00422 }
00423
00424 void RobotNavigator::printJointTrajectory(const trajectory_msgs::JointTrajectory &jt)
00425 {
00426
00427 ROS_INFO_STREAM(NODE_NAME<<": Total joint points: "<<jt.points.size()<<", total joints "<<jt.joint_names.size());
00428 std::stringstream ss;
00429 for(unsigned int j = 0; j < jt.points.size(); j++)
00430 {
00431 ROS_INFO_STREAM(NODE_NAME<<": joint point time: "<<jt.points[j].time_from_start.toSec());
00432 for(unsigned int i = 0;i < jt.joint_names.size(); i++)
00433 {
00434 ss<<NODE_NAME<<": joint "<<jt.joint_names[i]<<", pos: ";
00435 if(jt.points[j].positions.size() == 0)
00436 {
00437 ss<<"NAN";
00438 }
00439 else
00440 {
00441 ss<<jt.points[j].positions[i];
00442 }
00443
00444 ss<<", vel: ";
00445 if(jt.points[j].velocities.size() == 0)
00446 {
00447 ss<<"NAN";
00448 }
00449 else
00450 {
00451 ss<<jt.points[j].velocities[i];
00452 }
00453
00454 ss<<", acc: ";
00455 if(jt.points[j].velocities.size() == 0)
00456 {
00457 ss<<"NAN";
00458 }
00459 else
00460 {
00461 ss<<jt.points[j].accelerations[i];
00462 }
00463
00464 ROS_INFO_STREAM(ss.str());
00465 ss.str("");
00466 }
00467 }
00468 }
00469
00470 bool RobotNavigator::performTrajectoryFiltering(const std::string& group_name,trajectory_msgs::JointTrajectory& jt)
00471 {
00472 arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Request filter_req;
00473 arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Response filter_res;
00474
00475 ROS_INFO_STREAM(NODE_NAME<<": Performing fast filter trajectory");
00476 ROS_INFO_STREAM(NODE_NAME<<": Incoming number of joints: " << jt.joint_names.size());
00477 ROS_INFO_STREAM(NODE_NAME<<": Incoming number of points: " << jt.points.size());
00478
00479 std::map<std::string, double> jvals;
00480 for(unsigned int i = 0; i < jt.joint_names.size(); i++)
00481 {
00482 jvals[jt.joint_names[i]] = jt.points[0].positions[i];
00483
00484
00485
00486
00487 }
00488
00489 planning_models::KinematicState state(*current_robot_state_);
00490 state.setKinematicState(jvals);
00491
00492 filter_req.trajectory = jt;
00493 planning_environment::convertKinematicStateToRobotState(state,ros::Time::now(),
00494 cm_.getWorldFrameId(),filter_req.start_state);
00495 filter_req.group_name = group_name;
00496
00497 if(!trajectory_filter_service_client_.call(filter_req, filter_res))
00498 {
00499 ROS_WARN_STREAM(NODE_NAME<<": Fast Filter service call failed");
00500 return true;
00501 }
00502
00503 if (filter_res.trajectory.points.size() != 0)
00504 {
00505 jt = filter_res.trajectory;
00506 }
00507 else
00508 {
00509 ROS_WARN_STREAM(NODE_NAME<<": Filter returned an empty trajectory (ignoring for now)");
00510 }
00511
00512
00513 return true;
00514 }
00515
00516 bool RobotNavigator::moveArmToSide()
00517 {
00518 updateChangesToPlanningScene();
00519
00520 std::vector<double> joint_angles;
00521 joint_angles.push_back(-1.0410828590393066);
00522 joint_angles.push_back(0.46065822721369176);
00523 joint_angles.push_back(2.4644586717834467);
00524 joint_angles.push_back(0.49449136755439443);
00525 joint_angles.push_back(-0.2900361153401066);
00526 joint_angles.push_back(1.4113548618662812);
00527 joint_angles.push_back(2.3286899342716625);
00528
00529 return moveArm(arm_group_name_,joint_angles);
00530 }
00531
00532 void RobotNavigator::addDetectedTableToLocalPlanningScene(const tabletop_object_detector::Table &table)
00533 {
00534 arm_navigation_msgs::CollisionObject table_object;
00535 table_object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
00536 table_object.shapes.resize(1);
00537 table_object.shapes[0].type = arm_navigation_msgs::Shape::BOX;
00538 table_object.shapes[0].dimensions.resize(3);
00539 table_object.shapes[0].dimensions[0] = fabs(table.x_max-table.x_min);
00540 table_object.shapes[0].dimensions[1] = fabs(table.y_max-table.y_min);
00541 table_object.shapes[0].dimensions[2] = 0.01;
00542 table_object.id = "table";
00543
00544
00545 geometry_msgs::PoseStamped table_world;
00546 cm_.convertPoseGivenWorldTransform(*current_robot_state_,
00547 cm_.getWorldFrameId(),
00548 table.pose.header,
00549 table.pose.pose,
00550 table_world);
00551
00552 table_object.header = table_world.header;
00553
00554
00555 tf::Transform table_trans;
00556 tf::poseMsgToTF(table_world.pose, table_trans);
00557 tf::Transform table_translation;
00558 table_translation.setIdentity();
00559 table_translation.setOrigin( tf::Vector3( (table.x_min + table.x_max)/2.0, (table.y_min + table.y_max)/2.0, 0.0) );
00560 table_trans = table_trans * table_translation;
00561 table_object.poses.resize(1);
00562 tf::poseTFToMsg(table_trans, table_object.poses[0]);
00563
00564
00565 ROS_INFO_STREAM(NODE_NAME<<": Table location is " << table_object.poses[0].position.x << " "
00566 << table_object.poses[0].position.y << " "
00567 << table_object.poses[0].position.z);
00568
00569
00570 planning_scene_diff_.collision_objects.push_back(table_object);
00571 table_ = table_object;
00572 }
00573
00574 void RobotNavigator::addDetectedObjectToLocalPlanningScene(arm_navigation_msgs::CollisionObject &obj)
00575 {
00576 obj.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
00577 planning_scene_diff_.collision_objects.push_back(obj);
00578 }
00579
00580 void RobotNavigator::addDetectedObjectToLocalPlanningScene(const household_objects_database_msgs::DatabaseModelPoseList& model)
00581 {
00582 arm_navigation_msgs::CollisionObject obj;
00583 obj.id = makeCollisionObjectNameFromModelId(model.model_list[0].model_id);
00584
00585
00586 geometry_msgs::PoseStamped obj_world;
00587 cm_.convertPoseGivenWorldTransform(*current_robot_state_,
00588 cm_.getWorldFrameId(),
00589 model.model_list[0].pose.header,
00590 model.model_list[0].pose.pose,
00591 obj_world);
00592
00593 obj.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
00594 getMeshFromDatabasePose(model.model_list[0],obj,obj_world);
00595
00596 ROS_INFO_STREAM(NODE_NAME<<": Pushing back " << obj.id << " frame " << obj.header.frame_id);
00597 planning_scene_diff_.collision_objects.push_back(obj);
00598 }
00599
00600 bool RobotNavigator::performSegmentation()
00601 {
00602
00603 ros::WallTime start = ros::WallTime::now();
00604
00605
00606 planning_scene_diff_.collision_objects.clear();
00607 recognized_obj_pose_map_.clear();
00608
00609
00610 tabletop_object_detector::TabletopSegmentation segmentation_srv;
00611 bool success = seg_srv_.call(segmentation_srv);
00612
00613
00614 ros::WallTime after_seg = ros::WallTime::now();
00615 ROS_INFO_STREAM(NODE_NAME<<": Seg took " << (after_seg-start).toSec());
00616
00617
00618 if (!success)
00619 {
00620 ROS_ERROR_STREAM(NODE_NAME<<": Call to segmentation service failed");
00621 return false;
00622 }
00623
00624 if (segmentation_srv.response.result != segmentation_srv.response.SUCCESS)
00625 {
00626 ROS_ERROR_STREAM(NODE_NAME<<": Segmentation service returned error "<< segmentation_srv.response.result);
00627 return false;
00628 }
00629
00630 if(segmentation_srv.response.clusters.size() == 0)
00631 {
00632 ROS_ERROR_STREAM(NODE_NAME<<": Tabletop segmentation returned 0 clusters, exiting");
00633 return false;
00634 }
00635
00636
00637 segmentation_results_ = segmentation_srv.response;
00638 segmented_clusters_ = segmentation_srv.response.clusters;
00639
00640
00641 addDetectedTableToLocalPlanningScene(segmentation_srv.response.table);
00642
00643
00644 ROS_INFO_STREAM(NODE_NAME<<": Segmentation service succeeded. Detected "<<(int)segmentation_srv.response.clusters.size()<<" clusters");
00645
00646 return true;
00647 }
00648
00649 bool RobotNavigator::performRecognition()
00650 {
00651
00652 ros::WallTime start = ros::WallTime::now();
00653
00654
00655 planning_scene_diff_.collision_objects.clear();
00656 recognized_obj_pose_map_.clear();
00657
00658
00659 tabletop_object_detector::TabletopObjectRecognition recognition_srv;
00660 recognition_srv.request.table = segmentation_results_.table;
00661 recognition_srv.request.clusters = segmented_clusters_;
00662 recognition_srv.request.num_models = 1;
00663 recognition_srv.request.perform_fit_merge = false;
00664
00665 bool success = rec_srv_.call(recognition_srv);
00666
00667
00668 if (!success)
00669 {
00670 ROS_ERROR_STREAM(NODE_NAME<<": Call to recognition service " <<recognition_service_.c_str()<<" failed.");
00671 return false;
00672 }
00673
00674 if(recognition_srv.response.models.size() == 0)
00675 {
00676 ROS_ERROR_STREAM(NODE_NAME<<": Recognition found no objects");
00677 return false;
00678 }
00679
00680
00681 recognized_models_ = recognition_srv.response.models;
00682
00683
00684
00685 household_objects_database_msgs::GetModelDescription::Request des_req;
00686 household_objects_database_msgs::GetModelDescription::Response des_res;
00687 des_req.model_id = recognized_models_[0].model_list[0].model_id;
00688
00689 success = object_database_model_description_client_.call(des_req, des_res);
00690
00691
00692 if(!success)
00693 {
00694 ROS_WARN_STREAM(NODE_NAME<<": Call to objects database for getModelDescription failed");
00695 return false;
00696 }
00697
00698 if(des_res.return_code.code != des_res.return_code.SUCCESS)
00699 {
00700 ROS_WARN_STREAM(NODE_NAME<<":Object database gave non-success code "
00701 << des_res.return_code.code
00702 << " for model id "
00703 << des_req.model_id);
00704 return false;
00705 }
00706
00707
00708 recognized_model_description_ = des_res;
00709
00710
00711 addDetectedObjectToLocalPlanningScene(recognition_srv.response.models[0]);
00712
00713
00714 ROS_INFO_STREAM(NODE_NAME<<": Recognition took " << (ros::WallTime::now()-start));
00715 ROS_INFO_STREAM(NODE_NAME<<": Got " << recognition_srv.response.models.size() << " models");
00716 recognized_models_ = recognition_srv.response.models;
00717 std::stringstream stdout;
00718 stdout<<"\nRetrieved models:";
00719 BOOST_FOREACH(household_objects_database_msgs::DatabaseModelPose model,recognition_srv.response.models[0].model_list)
00720 {
00721 stdout<<"\n\tModel id: "<<model.model_id;
00722 stdout<<"\n\tPose frame id: "<<model.pose.header.frame_id;
00723 stdout<<"\n\tdetector name: "<<model.detector_name;
00724 stdout<<"\n";
00725 }
00726 ROS_INFO_STREAM(stdout.str());
00727 ROS_INFO_STREAM(NODE_NAME<<" model database service returned description with name: "<<des_res.name);
00728
00729 return true;
00730 }
00731
00732 bool RobotNavigator::getMeshFromDatabasePose(const household_objects_database_msgs::DatabaseModelPose &model_pose,
00733 arm_navigation_msgs::CollisionObject& obj,
00734 const geometry_msgs::PoseStamped& pose)
00735 {
00736 household_objects_database_msgs::GetModelMesh::Request req;
00737 household_objects_database_msgs::GetModelMesh::Response res;
00738
00739 req.model_id = model_pose.model_id;
00740 if(!object_database_model_mesh_client_.call(req, res))
00741 {
00742 ROS_WARN_STREAM(NODE_NAME<<": Call to objects database for getMesh failed");
00743 return false;
00744 }
00745
00746 if(res.return_code.code != res.return_code.SUCCESS)
00747 {
00748 ROS_WARN_STREAM(NODE_NAME<<": Object database gave non-success code " << res.return_code.code << " for model id " << req.model_id);
00749 return false;
00750 }
00751
00752 obj.header = pose.header;
00753 obj.poses.resize(1);
00754 obj.shapes.resize(1);
00755
00756 recognized_obj_pose_map_[obj.id] = pose;
00757
00758 bool use_cylinder = true;
00759
00760 if(use_cylinder)
00761 {
00762 tf::Transform pose_tf;
00763 tf::poseMsgToTF(pose.pose, pose_tf);
00764
00765 shapes::Shape* shape = planning_environment::constructObject(res.mesh);
00766 bodies::Body* body = bodies::createBodyFromShape(shape);
00767 body->setPose(pose_tf);
00768
00769 bodies::BoundingCylinder cyl;
00770 body->computeBoundingCylinder(cyl);
00771
00772 obj.shapes[0].type = arm_navigation_msgs::Shape::CYLINDER;
00773 obj.shapes[0].dimensions.resize(2);
00774 obj.shapes[0].dimensions[0] = cyl.radius;
00775 obj.shapes[0].dimensions[1] = cyl.length;
00776 tf::poseTFToMsg(cyl.pose, obj.poses[0]);
00777 }
00778 else
00779 {
00780 obj.shapes.resize(1);
00781 obj.shapes[0].type = arm_navigation_msgs::Shape::MESH;
00782 obj.shapes[0] = res.mesh;
00783 obj.poses[0] = pose.pose;
00784 }
00785 return true;
00786 }
00787
00788 bool RobotNavigator::performPickGraspPlanning()
00789 {
00790
00791 ros::WallTime start_time = ros::WallTime::now();
00792
00793
00794 grasp_pickup_goal_.target.potential_models.clear();
00795 grasp_candidates_.clear();
00796
00797
00798
00799 if((recognized_models_.size() == 0) || (recognized_models_[0].model_list.size() == 0))
00800 {
00801 return false;
00802 }
00803
00804
00805 household_objects_database_msgs::DatabaseModelPose modelPose = recognized_models_[0].model_list[0];
00806 object_manipulation_msgs::GraspPlanning::Request request;
00807 object_manipulation_msgs::GraspPlanning::Response response;
00808 std::string modelId = makeCollisionObjectNameFromModelId(modelPose.model_id);
00809
00810
00811
00812 modelPose.pose = recognized_obj_pose_map_[modelId];
00813 modelPose.pose.header.frame_id = recognized_model_description_.name;
00814 modelPose.pose.header.stamp = ros::Time::now();
00815 request.arm_name = arm_group_name_;
00816 request.target.potential_models.push_back(modelPose);
00817
00818 request.target.cluster = segmented_clusters_[0];
00819 request.target.reference_frame_id = segmentation_results_.table.pose.header.frame_id;
00820
00821 bool success = grasp_planning_client.call(request, response);
00822
00823
00824 if(!success)
00825 {
00826 ROS_WARN_STREAM(NODE_NAME<<": grasp planning call unsuccessful, exiting");
00827 return false;
00828 }
00829
00830 if(response.error_code.value != response.error_code.SUCCESS)
00831 {
00832 ROS_WARN_STREAM(NODE_NAME<<": grasp planning call returned error code, exiting " << response.error_code.value);
00833 return false;
00834 }
00835
00836 if(response.grasps.size() == 0)
00837 {
00838 ROS_WARN_STREAM(NODE_NAME<<": No grasps returned in response");
00839 return false;
00840 }
00841 else
00842 {
00843 ROS_INFO_STREAM(NODE_NAME<<": Grasp Planner Srcv returned "<<response.grasps.size()<<" grasp candidates");
00844 }
00845
00846
00847 if(request.target.reference_frame_id != recognized_model_description_.name ||
00848 request.target.reference_frame_id != modelPose.pose.header.frame_id)
00849 {
00850 ROS_WARN_STREAM("Cluster does not match recognition");
00851 }
00852
00853
00854
00855
00856
00857
00858
00859 grasp_candidates_.assign(response.grasps.begin(),response.grasps.end());
00860
00861
00862
00863 tf::Transform object_in_world_tf;
00864 tf::StampedTransform wristInGripperTcp = tf::StampedTransform();
00865 tf::Transform object_in_world_inverse_tf;
00866
00867
00868 tf::poseMsgToTF(modelPose.pose.pose, object_in_world_tf);
00869 object_in_world_inverse_tf = object_in_world_tf.inverse();
00870 _TfListener.lookupTransform(gripper_link_name_,wrist_link_name_,ros::Time(0),wristInGripperTcp);
00871
00872
00873 for(unsigned int i = 0; i < grasp_candidates_.size(); i++)
00874 {
00875 tf::Transform grasp_in_world_tf;
00876 tf::poseMsgToTF(grasp_candidates_[i].grasp_pose, grasp_in_world_tf);
00877 tf::poseTFToMsg(object_in_world_inverse_tf*(grasp_in_world_tf*wristInGripperTcp),
00878 grasp_candidates_[i].grasp_pose);
00879 }
00880
00881
00882 grasp_pickup_goal_.arm_name = arm_group_name_;
00883 grasp_pickup_goal_.collision_object_name = modelId;
00884 grasp_pickup_goal_.lift.direction.header.frame_id = cm_.getWorldFrameId();
00885 grasp_pickup_goal_.target.reference_frame_id = modelId;
00886 grasp_pickup_goal_.target.cluster = segmented_clusters_[0];
00887 grasp_pickup_goal_.target.potential_models.push_back(modelPose);
00888
00889
00890 updateChangesToPlanningScene();
00891 grasp_pick_sequence_.clear();
00892 std::vector<object_manipulation_msgs::Grasp> valid_grasps;
00893 if(!createPickMoveSequence(grasp_pickup_goal_,grasp_candidates_,grasp_pick_sequence_,valid_grasps))
00894 {
00895 ROS_ERROR_STREAM(NODE_NAME<<": Failed to create valid grasp pick sequence");
00896 return false;
00897 }
00898 grasp_candidates_.assign(valid_grasps.begin(),valid_grasps.end());
00899 return true;
00900 }
00901
00902 bool RobotNavigator::performPlaceGraspPlanning()
00903 {
00904 using namespace manipulation_utils;
00905
00906
00907 grasp_place_goal_.arm_name = arm_group_name_;
00908 grasp_place_goal_.approach.direction.header.frame_id = cm_.getWorldFrameId();
00909 grasp_place_goal_.collision_object_name = "attached_"+current_grasped_object_name_[arm_group_name_];
00910
00911
00912 std::vector<geometry_msgs::PoseStamped> placePoses;
00913 if(!createCandidateGoalPoses(placePoses))
00914 {
00915 ROS_ERROR_STREAM(NODE_NAME<<": Could not create valid place poses");
00916 return false;
00917 }
00918
00919
00920 updateChangesToPlanningScene();
00921 bool found_valid = false;
00922 geometry_msgs::Pose valid_grasp_place_pose;
00923 std::vector<object_manipulation_msgs::Grasp> valid_grasps;
00924 std::vector<object_manipulator::GraspExecutionInfo> valid_pick_sequence;
00925 std::vector<object_manipulator::PlaceExecutionInfo> valid_place_sequence;
00926
00927
00928 tf::StampedTransform wrist_in_tcp_tf, wrist_in_obj_tf;
00929 _TfListener.lookupTransform(gripper_link_name_,wrist_link_name_,ros::Time(0),wrist_in_tcp_tf);
00930 for(std::size_t i = 0; i < grasp_candidates_.size(); i++)
00931 {
00932
00933 tf::poseMsgToTF(grasp_candidates_[i].grasp_pose,wrist_in_obj_tf);
00934 tf::poseTFToMsg(wrist_in_obj_tf*(wrist_in_tcp_tf.inverse()),grasp_place_goal_.grasp.grasp_pose);
00935 manipulation_utils::rectifyPoseZDirection(grasp_place_goal_.grasp.grasp_pose,
00936 PLACE_RECTIFICATION_TF,grasp_place_goal_.grasp.grasp_pose);
00937 if(createPlaceMoveSequence(grasp_place_goal_,placePoses,valid_place_sequence))
00938 {
00939 if(!found_valid)
00940 {
00941
00942 grasp_place_sequence_.assign(valid_place_sequence.begin(),valid_place_sequence.end());
00943 valid_grasp_place_pose = grasp_place_goal_.grasp.grasp_pose;
00944 }
00945
00946 found_valid = true;
00947 valid_grasps.push_back(grasp_candidates_[i]);
00948 valid_pick_sequence.push_back(grasp_pick_sequence_[i]);
00949
00950 }
00951 }
00952
00953 if(!found_valid)
00954 {
00955 ROS_ERROR_STREAM(NODE_NAME<<": Failed to create valid grasp place sequence");
00956 return false;
00957 }
00958 else
00959 {
00960
00961 grasp_candidates_.assign(valid_grasps.begin(),valid_grasps.end());
00962 grasp_pick_sequence_.assign(valid_pick_sequence.begin(),valid_pick_sequence.end());
00963 grasp_place_goal_.grasp.grasp_pose = valid_grasp_place_pose;
00964 }
00965
00966
00967
00968
00969 tf::Transform first_grasp_in_world_tf;
00970 tf::poseMsgToTF(grasp_candidates_[0].grasp_pose, first_grasp_in_world_tf);
00971 planning_models::KinematicState state(*current_robot_state_);
00972 state.updateKinematicStateWithLinkAt(gripper_link_name_, first_grasp_in_world_tf);
00973
00974 return true;
00975 }
00976
00977 bool RobotNavigator::performGraspPlanning()
00978 {
00979
00980 return performPickGraspPlanning() && performPlaceGraspPlanning();
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 }
01159
01160 bool RobotNavigator::createPickMoveSequence(
01161 const object_manipulation_msgs::PickupGoal &pickupGoal,
01162 const std::vector<object_manipulation_msgs::Grasp> &grasps_candidates,
01163 std::vector<object_manipulator::GraspExecutionInfo> &grasp_sequence,
01164 std::vector<object_manipulation_msgs::Grasp> &valid_grasps)
01165 {
01166
01167 std::vector<object_manipulator::GraspExecutionInfo> candidate_sequence;
01168
01169 ROS_INFO_STREAM(NODE_NAME<<": Evaluating grasps with grasp tester");
01170 planning_models::KinematicState kinematicState(*current_robot_state_);
01171 grasp_tester_->setPlanningSceneState(&kinematicState);
01172 grasp_tester_->testGrasps(pickupGoal,grasps_candidates,candidate_sequence,true);
01173
01174
01175 bool found_valid = false;
01176 for(std::size_t i = 0; i < candidate_sequence.size(); i++)
01177 {
01178 if(candidate_sequence[i].result_.result_code == object_manipulation_msgs::GraspResult::SUCCESS)
01179 {
01180 grasp_sequence.push_back(candidate_sequence[i]);
01181 valid_grasps.push_back(grasp_candidates_[i]);
01182 found_valid = true;
01183 }
01184 }
01185
01186 ROS_INFO_STREAM(NODE_NAME<<": Returned "<< grasp_sequence.size() <<" grasps candidates ");
01187 return found_valid;
01188 }
01189
01190 bool RobotNavigator::createPlaceMoveSequence(const object_manipulation_msgs::PlaceGoal &placeGoal,
01191 const std::vector<geometry_msgs::PoseStamped> &place_poses,
01192 std::vector<object_manipulator::PlaceExecutionInfo> &place_sequence)
01193 {
01194
01195 std::vector<object_manipulator::PlaceExecutionInfo> candidate_sequence;
01196
01197
01198 tf::StampedTransform gripperTcpToWrist = tf::StampedTransform();
01199 planning_models::KinematicState state(*current_robot_state_);
01200 _TfListener.lookupTransform(gripper_link_name_,wrist_link_name_,ros::Time(0),gripperTcpToWrist);
01201 place_tester_->setTcpToWristTransform(gripperTcpToWrist);
01202 place_tester_->setPlanningSceneState(&state);
01203 place_tester_->testPlaces(placeGoal, place_poses, candidate_sequence, true);
01204
01205
01206 bool found_valid = false;
01207 std::vector<object_manipulator::PlaceExecutionInfo>::iterator i;
01208 for(i = candidate_sequence.begin(); i != candidate_sequence.end();i++)
01209 {
01210 if(i->result_.result_code == object_manipulation_msgs::PlaceLocationResult::SUCCESS)
01211 {
01212 place_sequence.push_back(*i);
01213 found_valid = true;
01214 }
01215 }
01216
01217 return found_valid;
01218 }
01219
01220 bool RobotNavigator::moveArmThroughPickSequence()
01221 {
01222
01223 using namespace manipulation_utils;
01224
01225 updateChangesToPlanningScene();
01226
01227
01228 bool success = performGraspPlanning();
01229 if(!success)
01230 {
01231 ROS_INFO_STREAM(NODE_NAME<<": Grasp Pick attempt aborted");
01232 return false;
01233 }
01234
01235
01236 tf::StampedTransform wrist_in_tcp_tf;
01237 tf::Transform wrist_in_obj_tf;
01238 _TfListener.lookupTransform(gripper_link_name_,wrist_link_name_,ros::Time(0),wrist_in_tcp_tf);
01239
01240
01241 success = false;
01242 int counter = 0;
01243 BOOST_FOREACH(object_manipulator::GraspExecutionInfo graspMoves,grasp_pick_sequence_)
01244 {
01245 ROS_INFO_STREAM(NODE_NAME<<": Attempting Grasp Pick sequence");
01246 success = attemptGraspSequence(arm_group_name_,graspMoves);
01247 if(!success)
01248 {
01249 if(++counter == (int)grasp_pick_sequence_.size()) return false;
01250
01251 tf::poseMsgToTF(grasp_candidates_[counter].grasp_pose,wrist_in_obj_tf);
01252 tf::poseTFToMsg(wrist_in_obj_tf*(wrist_in_tcp_tf.inverse()),grasp_place_goal_.grasp.grasp_pose);
01253 manipulation_utils::rectifyPoseZDirection(grasp_place_goal_.grasp.grasp_pose,
01254 PLACE_RECTIFICATION_TF,grasp_place_goal_.grasp.grasp_pose);
01255
01256
01257 std::vector<geometry_msgs::PoseStamped> placePoses;
01258 if(!createCandidateGoalPoses(placePoses) || !createPlaceMoveSequence(grasp_place_goal_,placePoses,grasp_place_sequence_))
01259 {
01260 ROS_ERROR_STREAM(NODE_NAME<<": Could not grasp place solution for current grasp pick");
01261 return false;
01262 }
01263
01264 ROS_INFO_STREAM(NODE_NAME<<": Grasp pick move failed, try next");
01265
01266 continue;
01267 }
01268 else
01269 {
01270 ROS_INFO_STREAM(NODE_NAME<<": Grasp pick move succeeded");
01271 }
01272
01273
01274 if(hasMarker(MARKER_ATTACHED_OBJECT))
01275 {
01276 visualization_msgs::Marker &m = getMarker(MARKER_ATTACHED_OBJECT);
01277 tf::poseTFToMsg(wrist_in_obj_tf.inverse(),m.pose);
01278 m.header.frame_id = gripper_link_name_;
01279 addMarker(MARKER_ATTACHED_OBJECT,m);
01280 }
01281
01282 counter++;
01283 }
01284
01285 return success;
01286 }
01287
01288 bool RobotNavigator::moveArmThroughPlaceSequence()
01289 {
01290
01291 updateChangesToPlanningScene();
01292
01293
01294 ros::WallTime start_time = ros::WallTime::now();
01295
01296
01297 if(!object_in_hand_map_[arm_group_name_])
01298 {
01299 ROS_WARN_STREAM(NODE_NAME<<": No object in hand reported, continuing");
01300
01301 }
01302
01303
01304 grasp_place_goal_.collision_object_name = "attached_"+current_grasped_object_name_[arm_group_name_];
01305
01306
01307 bool success = false;
01308 BOOST_FOREACH(object_manipulator::PlaceExecutionInfo placeMove,grasp_place_sequence_)
01309 {
01310 success = attemptPlaceSequence(arm_group_name_,placeMove);
01311 if(success)
01312 {
01313 ROS_INFO_STREAM(NODE_NAME<<": Grasp place move succeeded");
01314 }
01315 else
01316 {
01317 ROS_ERROR_STREAM(NODE_NAME<<"Grasp place move failed, , trying next");
01318
01319 continue;
01320 }
01321
01322 break;
01323 }
01324
01325 return success;
01326 }
01327
01328 void RobotNavigator::addMarker(std::string name,visualization_msgs::Marker &marker)
01329 {
01330 if(marker_map_.count(name) > 0)
01331 {
01332 marker.id = marker_map_[name].id;
01333 marker_map_[name] = marker;
01334 }
01335 else
01336 {
01337 marker.id = marker_map_.size();
01338 marker_map_.insert(std::make_pair(name,marker));
01339 }
01340 }
01341
01342 void RobotNavigator::addMarker(std::string name,visualization_msgs::MarkerArray &markers)
01343 {
01344 std::stringstream nameStream;
01345 for(unsigned int i = 0; i < markers.markers.size(); i++)
01346 {
01347 nameStream<<name<<i;
01348 addMarker(nameStream.str(),markers.markers[i]);
01349 nameStream.str("");
01350 }
01351 }
01352
01353 bool RobotNavigator::hasMarker(std::string name)
01354 {
01355 if(marker_map_.count(name) > 0)
01356 {
01357 return true;
01358 }
01359 else
01360 {
01361 return false;
01362 }
01363 }
01364
01365 visualization_msgs::Marker& RobotNavigator::getMarker(std::string name)
01366 {
01367 return marker_map_[name];
01368 }
01369
01370 void RobotNavigator::callbackPublishMarkers(const ros::TimerEvent &evnt)
01371 {
01372 for(std::map<std::string,visualization_msgs::Marker>::iterator i = marker_map_.begin(); i != marker_map_.end(); i++)
01373 {
01374 visualization_msgs::Marker &m = i->second;
01375 m.header.stamp = ros::Time::now();
01376 marker_publisher_.publish(m);
01377 }
01378 }
01379
01380 void RobotNavigator::attachCollisionObjectCallback(const std::string& group_name)
01381 {
01382 attachCollisionObject(group_name,
01383 current_grasped_object_name_[group_name],
01384 current_grasp_map_[group_name]);
01385 object_in_hand_map_[group_name] = true;
01386 }
01387
01388 void RobotNavigator::detachCollisionObjectCallback(const std::string& group_name)
01389 {
01390 detachCollisionObject(group_name,
01391 current_place_location_,
01392 current_grasp_map_[group_name]);
01393 object_in_hand_map_[group_name] = false;
01394 current_grasped_object_name_.erase(group_name);
01395 current_grasp_map_.erase(group_name);
01396 }
01397
01398 bool RobotNavigator::attemptGraspSequence(const std::string& group_name,
01399 const object_manipulator::GraspExecutionInfo& gei,
01400 bool performRecoveryMove)
01401 {
01402
01403 std::vector<std::string> segment_names;
01404 std::vector< boost::function<bool(TrajectoryExecutionDataVector)> > callbacks;
01405
01406
01407 std::vector<TrajectoryExecutionRequest> ter_reqs;
01408 TrajectoryExecutionRequest gripper_ter;
01409 gripper_ter.group_name_ = gripper_group_name_;
01410 gripper_ter.controller_name_ = grasp_action_service_;
01411 gripper_ter.trajectory_ = getGripperTrajectory(object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE);
01412 gripper_ter.failure_ok_ = false;
01413 gripper_ter.test_for_close_enough_ = false;
01414
01415 ter_reqs.push_back(gripper_ter);
01416
01417 ros::WallTime start_execution = ros::WallTime::now();
01418 ROS_INFO_STREAM(NODE_NAME << ": Gripper Release trajectory in progress");
01419
01420 trajectory_execution_monitor_.executeTrajectories(ter_reqs,grasp_action_finished_function_);
01421 {
01422 boost::unique_lock<boost::mutex> lock(execution_mutex_);
01423 execution_completed_.wait(lock);
01424 }
01425
01426 execution_duration_ += (ros::WallTime::now()-start_execution);
01427 ROS_INFO_STREAM( NODE_NAME << ": Gripper Release trajectory completed");
01428 ter_reqs.clear();
01429
01430
01431 updateCurrentJointStateToLastTrajectoryPoint(last_trajectory_execution_data_vector_.back().recorded_trajectory_);
01432 ROS_INFO_STREAM(NODE_NAME << ": Moving arm to beginning of pick trajectory");
01433 if(!moveArm(group_name, gei.approach_trajectory_.points[0].positions))
01434 {
01435 return false;
01436 }
01437 ROS_INFO_STREAM(NODE_NAME << ": Move completed");
01438 trajectories_succeeded_ = false;
01439
01440
01441 gripper_ter.trajectory_ = getGripperTrajectory(object_manipulation_msgs::GraspHandPostureExecutionGoal::PRE_GRASP);
01442 validateJointTrajectory(gripper_ter.trajectory_);
01443 ter_reqs.push_back(gripper_ter);
01444 segment_names.push_back("Pre-grasp");
01445 callbacks.push_back(grasp_action_finished_function_);
01446
01447
01448 TrajectoryExecutionRequest arm_ter;
01449 arm_ter.group_name_ = group_name;
01450 arm_ter.controller_name_ = arm_controller_handler_->getControllerName();
01451 arm_ter.trajectory_ = gei.approach_trajectory_;
01452 validateJointTrajectory(arm_ter.trajectory_);
01453 performTrajectoryFiltering(arm_ter.group_name_, arm_ter.trajectory_);
01454 arm_ter.test_for_close_enough_ = false;
01455 arm_ter.monitor_overshoot_ = false;
01456 arm_ter.min_overshoot_time_ = ros::Duration(0.0f);
01457 arm_ter.max_overshoot_time_ = ros::Duration(5.0f);
01458 arm_ter.failure_ok_ = false;
01459 arm_ter.max_joint_distance_ = .1;
01460 arm_ter.failure_time_factor_ = 1000;
01461 arm_ter.callback_function_ = boost::bind(&RobotNavigator::attachCollisionObjectCallback, this, _1);
01462 ter_reqs.push_back(arm_ter);
01463 segment_names.push_back("Approach");
01464 callbacks.push_back(trajectories_finished_function_);
01465
01466
01467 gripper_ter.trajectory_ = getGripperTrajectory(object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP);
01468 validateJointTrajectory(gripper_ter.trajectory_);
01469 ter_reqs.push_back(gripper_ter);
01470 segment_names.push_back("Grasp");
01471 callbacks.push_back(grasp_action_finished_function_);
01472
01473
01474 if(hasMarker(MARKER_ATTACHED_OBJECT))
01475 {
01476 visualization_msgs::Marker &m = getMarker(MARKER_ATTACHED_OBJECT);
01477 m.action = visualization_msgs::Marker::ADD;
01478 addMarker(MARKER_ATTACHED_OBJECT,m);
01479 }
01480
01481
01482 arm_ter.trajectory_ = gei.lift_trajectory_;
01483 validateJointTrajectory(arm_ter.trajectory_);
01484 performTrajectoryFiltering(group_name, arm_ter.trajectory_);
01485 arm_ter.callback_function_ = NULL;
01486 ter_reqs.push_back(arm_ter);
01487 segment_names.push_back("Lift");
01488 callbacks.push_back(trajectories_finished_function_);
01489
01490
01491
01492
01493
01494
01495 start_execution = ros::WallTime::now();
01496 ROS_INFO_STREAM(" Starting Execution of trajectories");
01497 for(unsigned int i = 0;i < ter_reqs.size(); i++)
01498 {
01499 std::vector<TrajectoryExecutionRequest> tempRequest;
01500 tempRequest.push_back(ter_reqs[i]);
01501 ROS_INFO_STREAM("\t- "<<segment_names[i] <<" trajectory in progress");
01502
01503
01504 trajectory_execution_monitor_.executeTrajectories(tempRequest,callbacks[i]);
01505 {
01506 boost::unique_lock<boost::mutex> lock(execution_mutex_);
01507 execution_completed_.wait(lock);
01508
01509 if(trajectories_succeeded_)
01510 {
01511 ROS_INFO_STREAM("\t- "<<segment_names[i] <<" trajectory completed");
01512 }
01513 else
01514 {
01515 ROS_ERROR_STREAM("\t- "<<segment_names[i] <<" trajectory interrupted, aborting pick move sequence");
01516 break;
01517 }
01518 }
01519
01520 }
01521
01522
01523 if(!trajectories_succeeded_ && performRecoveryMove)
01524 {
01525 updateCurrentJointStateToLastTrajectoryPoint(last_trajectory_execution_data_vector_.back().recorded_trajectory_);
01526
01527
01528 ROS_WARN_STREAM(" Starting recovery move");
01529 ROS_WARN_STREAM("\t- Moving arm to beginning of approach move trajectory");
01530 if(!moveArm(group_name, gei.approach_trajectory_.points[0].positions))
01531 {
01532 ROS_ERROR_STREAM("\t-"<< "Move start pose failed, aborting recovery move");
01533 return false;
01534 }
01535
01536
01537 object_manipulation_msgs::GraspHandPostureExecutionGoal graspGoal;
01538 graspGoal.goal = object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE;
01539 ROS_WARN_STREAM("\t- Requesting grasp release");
01540 grasp_exec_action_client_->sendGoal(graspGoal);
01541 if(!grasp_exec_action_client_->waitForResult(ros::Duration(2.0f)))
01542 {
01543 ROS_ERROR_STREAM(" Release request timeout, aborting recovery move");
01544 }
01545
01546 ROS_WARN_STREAM(" Completed recovery move");
01547 return false;
01548 }
01549
01550 ROS_INFO_STREAM("Finished executing all trajectories");
01551 execution_duration_ += (ros::WallTime::now()-start_execution);
01552 return trajectories_succeeded_ ;
01553 }
01554
01555 bool RobotNavigator::attemptPlaceSequence(const std::string& group_name,
01556 const object_manipulator::PlaceExecutionInfo& pei) {
01557 std::vector<TrajectoryExecutionRequest> ter_reqs;
01558
01559
01560 if(!moveArm(group_name,pei.descend_trajectory_.points[0].positions))
01561 {
01562 return false;
01563 }
01564
01565 trajectories_succeeded_ = false;
01566 std::vector<std::string> segment_names;
01567 std::vector<boost::function<bool(TrajectoryExecutionDataVector)> > callbacks;
01568
01569
01570 TrajectoryExecutionRequest arm_ter;
01571 arm_ter.group_name_ = group_name;
01572 arm_ter.controller_name_ = arm_controller_handler_->getControllerName();
01573 arm_ter.trajectory_ = pei.descend_trajectory_;
01574 validateJointTrajectory(arm_ter.trajectory_);
01575 performTrajectoryFiltering(group_name, arm_ter.trajectory_);
01576 arm_ter.failure_ok_ = false;
01577 arm_ter.monitor_overshoot_ = false;
01578 arm_ter.min_overshoot_time_ = ros::Duration(0.0f);
01579 arm_ter.max_overshoot_time_ = ros::Duration(5.0f);
01580 arm_ter.max_joint_distance_ = .1;
01581 arm_ter.failure_time_factor_ = 1000;
01582 arm_ter.callback_function_ = boost::bind(&RobotNavigator::detachCollisionObjectCallback, this, _1);
01583 ter_reqs.push_back(arm_ter);
01584 segment_names.push_back("Descend");
01585 callbacks.push_back(trajectories_finished_function_);
01586
01587
01588 TrajectoryExecutionRequest gripper_ter;
01589 gripper_ter.group_name_ = gripper_group_name_;
01590 gripper_ter.controller_name_ = grasp_action_service_;
01591 gripper_ter.trajectory_ = getGripperTrajectory(object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE);
01592 validateJointTrajectory(gripper_ter.trajectory_);
01593 gripper_ter.failure_ok_ = true;
01594 gripper_ter.test_for_close_enough_ = false;
01595 ter_reqs.push_back(gripper_ter);
01596 segment_names.push_back("Release");
01597 callbacks.push_back(grasp_action_finished_function_);
01598
01599
01600 if(hasMarker(MARKER_ATTACHED_OBJECT))
01601 {
01602 visualization_msgs::Marker &m = getMarker(MARKER_ATTACHED_OBJECT);
01603 m.action = visualization_msgs::Marker::DELETE;
01604 addMarker(MARKER_ATTACHED_OBJECT,m);
01605 }
01606
01607
01608 arm_ter.trajectory_ = pei.retreat_trajectory_;
01609 validateJointTrajectory(arm_ter.trajectory_);
01610 performTrajectoryFiltering(group_name, arm_ter.trajectory_);
01611 arm_ter.callback_function_ = 0;
01612 ter_reqs.push_back(arm_ter);
01613 segment_names.push_back("Retreat");
01614 callbacks.push_back(trajectories_finished_function_);
01615
01616
01617
01618
01619
01620
01621 ros::WallTime start_execution = ros::WallTime::now();
01622 ROS_INFO_STREAM( NODE_NAME <<": Starting Execution of trajectories");
01623 for(unsigned int i = 0;i < ter_reqs.size(); i++)
01624 {
01625 std::vector<TrajectoryExecutionRequest> tempRequest;
01626 tempRequest.push_back(ter_reqs[i]);
01627
01628 ROS_INFO_STREAM("\t"<< "- "<<segment_names[i] <<" trajectory in progress");
01629 trajectory_execution_monitor_.executeTrajectories(tempRequest,callbacks[i]);
01630
01631 {
01632 boost::unique_lock<boost::mutex> lock(execution_mutex_);
01633 execution_completed_.wait(lock);
01634
01635 if(trajectories_succeeded_)
01636 {
01637 ROS_INFO_STREAM("\t"<< "- "<<segment_names[i] <<" trajectory completed");
01638 }
01639 else
01640 {
01641 ROS_INFO_STREAM("\t"<< "- "<<segment_names[i] <<" trajectory interrupted, aborting place sequence");
01642 break;
01643 }
01644 }
01645 }
01646 ROS_INFO_STREAM(NODE_NAME <<"Finished executing all trajectories");
01647
01648 execution_duration_ += (ros::WallTime::now()-start_execution);
01649 return trajectories_succeeded_;
01650 }
01651
01652 trajectory_msgs::JointTrajectory RobotNavigator::getGripperTrajectory(int graspMove)
01653 {
01654 trajectory_msgs::JointTrajectoryPoint jp;
01655 trajectory_msgs::JointTrajectory gt;
01656
01657 gt.joint_names.push_back("j");
01658 gt.points.resize(1);
01659 gt.points[0].positions.resize(1, .1);
01660 gt.points[0].positions[0] = (double) graspMove;
01661
01662 return gt;
01663 }
01664
01665 bool RobotNavigator::attachCollisionObject(const std::string& group_name,
01666 const std::string& collision_object_name,
01667 const object_manipulation_msgs::Grasp& grasp) {
01668
01669
01670 arm_navigation_msgs::AttachedCollisionObject att;
01671 bool found = false;
01672 for(std::vector<arm_navigation_msgs::CollisionObject>::iterator it = planning_scene_diff_.collision_objects.begin();
01673 it != planning_scene_diff_.collision_objects.end();
01674 it++)
01675 {
01676
01677 if((*it).id == collision_object_name)
01678 {
01679 found = true;
01680 att.object = (*it);
01681 planning_scene_diff_.collision_objects.erase(it);
01682 break;
01683 }
01684 }
01685
01686 if(!found)
01687 {
01688 ROS_ERROR_STREAM("No object with id " << collision_object_name);
01689 return false;
01690 }
01691
01692 att.link_name = gripper_link_name_;
01693 att.touch_links.push_back(gripper_group_name_);
01694
01695 planning_models::KinematicState state(*current_robot_state_);
01696 tf::Transform t;
01697 tf::poseMsgToTF(grasp.grasp_pose, t);
01698
01699 std::map<std::string, double> grasp_vals;
01700 for(unsigned int i = 0; i < grasp.grasp_posture.name.size(); i ++)
01701 {
01702 grasp_vals[grasp.grasp_posture.name[i]] = grasp.grasp_posture.position[i];
01703 }
01704 state.setKinematicState(grasp_vals);
01705
01706 tf::Transform obj_pose;
01707 tf::poseMsgToTF(recognized_obj_pose_map_[collision_object_name].pose, obj_pose);
01708
01709
01710 tf::Transform grasp_pose = obj_pose*t;
01711
01712
01713 state.updateKinematicStateWithLinkAt(gripper_link_name_, grasp_pose);
01714
01715 geometry_msgs::PoseStamped ps;
01716
01717 cm_.convertPoseGivenWorldTransform(state,
01718 att.link_name,
01719 att.object.header,
01720 att.object.poses[0],
01721 ps);
01722
01723 att.object.id = "attached_"+att.object.id;
01724 att.object.header = ps.header;
01725 att.object.poses[0] = ps.pose;
01726
01727 ROS_INFO_STREAM("object pose is relative to " + gripper_link_name_ + ": "
01728 << ps.pose.position.x << " "
01729 << ps.pose.position.y << " "
01730 << ps.pose.position.z);
01731
01732 ROS_INFO_STREAM("Attaching " << att.object.id << " mode " << att.object.operation.operation);
01733 planning_scene_diff_.attached_collision_objects.push_back(att);
01734
01735 attached_object_publisher_.publish(att);
01736 return true;
01737 }
01738
01739 bool RobotNavigator::detachCollisionObject(const std::string& group_name,
01740 const geometry_msgs::PoseStamped& place_pose,
01741 const object_manipulation_msgs::Grasp& grasp) {
01742
01743 ROS_INFO_STREAM("Place pose is " << place_pose.header.frame_id);
01744
01745 planning_models::KinematicState state(*current_robot_state_);
01746 tf::Transform place_pose_tf;
01747 tf::poseMsgToTF(place_pose.pose, place_pose_tf);
01748
01749 tf::Transform grasp_trans;
01750 tf::poseMsgToTF(grasp.grasp_pose, grasp_trans);
01751
01752 place_pose_tf = place_pose_tf*grasp_trans;
01753
01754 state.updateKinematicStateWithLinkAt(gripper_link_name_,
01755 place_pose_tf);
01756
01757 if(planning_scene_diff_.attached_collision_objects.size() == 0) {
01758 ROS_ERROR_STREAM("No attached bodies in scene");
01759 return false;
01760 }
01761
01762 arm_navigation_msgs::CollisionObject& obj = planning_scene_diff_.attached_collision_objects.front().object;
01763 const planning_models::KinematicState::AttachedBodyState* att = state.getAttachedBodyState(obj.id);
01764 if(att == NULL) {
01765 ROS_ERROR_STREAM("No attached body model " << obj.id << " in attached");
01766 return false;
01767 }
01768
01769 arm_navigation_msgs::AttachedCollisionObject att_publish;
01770 att_publish.object.id = obj.id;
01771 att_publish.object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::REMOVE;
01772 attached_object_publisher_.publish(att_publish);
01773
01774 obj.header.frame_id = cm_.getWorldFrameId();
01775 tf::poseTFToMsg(att->getGlobalCollisionBodyTransforms()[0], obj.poses[0]);
01776 obj.id = current_grasped_object_name_[group_name];
01777 planning_scene_diff_.collision_objects.push_back(obj);
01778 planning_scene_diff_.attached_collision_objects.clear();
01779 return true;
01780 }
01781
01782 void RobotNavigator::collisionObjToMarker(const arm_navigation_msgs::CollisionObject &obj,visualization_msgs::Marker &marker)
01783 {
01784
01785 const arm_navigation_msgs::Shape &shape = obj.shapes[0];
01786
01787 switch(shape.type)
01788 {
01789 case arm_navigation_msgs::Shape::SPHERE:
01790
01791 marker.header.frame_id = obj.header.frame_id;
01792 marker.type = visualization_msgs::Marker::SPHERE;
01793 marker.pose = obj.poses[0];
01794 marker.scale.x = 2*shape.dimensions[0];
01795 marker.scale.y =2*shape.dimensions[0];
01796 marker.scale.z =2*shape.dimensions[0];
01797 marker.color.a = 1.0;
01798 marker.color.r = 0.0;
01799 marker.color.g = 1.0;
01800 marker.color.b = 0.0;
01801
01802 break;
01803
01804 default:
01805
01806 break;
01807
01808 }
01809
01810 }
01811
01812 void RobotNavigator::startCycleTimer()
01813 {
01814 execution_duration_ = ros::WallDuration(0.0);
01815 perception_duration_ = ros::WallDuration(0.0);
01816 planning_scene_duration_ = ros::WallDuration(0.0);
01817 motion_planning_duration_ = ros::WallDuration(0.0);
01818 trajectory_filtering_duration_ = ros::WallDuration(0.0);
01819 grasp_planning_duration_ = ros::WallDuration(0.0);
01820 cycle_start_time_ = ros::WallTime::now();
01821 }
01822
01823 void RobotNavigator::printTiming()
01824 {
01825 ros::WallDuration dur = ros::WallTime::now()-cycle_start_time_;
01826 ROS_INFO_STREAM("Cycle took " << dur.toSec() << " processing " << (dur-execution_duration_).toSec() << " execution " << execution_duration_.toSec());
01827 ROS_INFO_STREAM("Perception " << perception_duration_.toSec());
01828 ROS_INFO_STREAM("Planning scene " << planning_scene_duration_.toSec());
01829 ROS_INFO_STREAM("Planning time " << motion_planning_duration_.toSec());
01830 ROS_INFO_STREAM("Filtering time " << trajectory_filtering_duration_.toSec());
01831 ROS_INFO_STREAM("Grasp planning time " << grasp_planning_duration_.toSec());
01832 }
01833
01834 std::string RobotNavigator::makeCollisionObjectNameFromModelId(unsigned int model_id)
01835 {
01836 std::stringstream object_id;
01837 object_id << "object_" << model_id;
01838 return object_id.str();
01839 }
01840
01841 const arm_navigation_msgs::CollisionObject* RobotNavigator::getCollisionObject(unsigned int model_id)
01842 {
01843 std::string name = makeCollisionObjectNameFromModelId(model_id);
01844 for(unsigned int i = 0; i < planning_scene_diff_.collision_objects.size(); i++) {
01845 if(planning_scene_diff_.collision_objects[i].id == name) return &(planning_scene_diff_.collision_objects[i]);
01846 }
01847 return NULL;
01848 }
01849
01850 void RobotNavigator::run()
01851 {
01852 ros::NodeHandle nh;
01853 ros::AsyncSpinner spinner(4);
01854 spinner.start();
01855 srand(time(NULL));
01856
01857 setup();
01858
01859 if(!moveArmToSide())
01860 {
01861 ROS_WARN_STREAM(NODE_NAME << ": Side moved failed");
01862 }
01863
01864 while(ros::ok())
01865 {
01866 startCycleTimer();
01867
01868
01869 ROS_INFO_STREAM(NODE_NAME + ": Segmentation stage started");
01870 if(!performSegmentation())
01871 {
01872 ROS_WARN_STREAM(NODE_NAME<<": Segmentation stage failed");
01873 continue;
01874 }
01875 ROS_INFO_STREAM(NODE_NAME << " Segmentation stage completed");
01876
01877 ROS_INFO_STREAM(NODE_NAME << ": Recognition stage started");
01878 if(!performRecognition())
01879 {
01880 ROS_WARN_STREAM(NODE_NAME << ": Recognition stage failed");
01881 continue;
01882 }
01883 else
01884 {
01885 ROS_INFO_STREAM(NODE_NAME << ": Recognition stage completed");
01886 }
01887
01888 ROS_INFO_STREAM(NODE_NAME << ": Grasp Pickup stage started");
01889 if(!moveArmThroughPickSequence())
01890 {
01891 ROS_WARN_STREAM(NODE_NAME << ": Grasp Pickup stage failed");
01892 moveArmToSide();
01893 continue;
01894 }
01895 else
01896 {
01897 ROS_INFO_STREAM(NODE_NAME << ": Grasp Pickup stage completed");
01898 }
01899
01900 ROS_INFO_STREAM(NODE_NAME + ": Grasp Place stage started");
01901 if(!moveArmThroughPlaceSequence())
01902 {
01903 ROS_WARN_STREAM(NODE_NAME << ": Grasp Place stage failed");
01904 moveArmToSide();
01905 continue;
01906 }
01907 else
01908 {
01909 ROS_INFO_STREAM(NODE_NAME << ": Grasp Place stage completed");
01910 }
01911
01912 if(!moveArmToSide())
01913 {
01914 ROS_WARN_STREAM(NODE_NAME << ": Side moved failed");
01915 }
01916
01917
01918 printTiming();
01919 }
01920 }
01921
01922
01923