reactive_grasping_node.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * \file
00003  *
00004  * $Id:$
00005  *
00006  * Copyright (C) Brno University of Technology
00007  *
00008  * This file is part of software developed by dcgm-robotics@FIT group.
00009  *
00010  * Author: Zdenek Materna (imaterna@fit.vutbr.cz)
00011  * Supervised by: Michal Spanel (spanel@fit.vutbr.cz)
00012  * Date: dd/mm/2012
00013  *
00014  * This file is free software: you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as published by
00016  * the Free Software Foundation, either version 3 of the License, or
00017  * (at your option) any later version.
00018  *
00019  * This file is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU Lesser General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this file.  If not, see <http://www.gnu.org/licenses/>.
00026  */
00027 
00028 #include <srs_assisted_grasping/reactive_grasping_node.h>
00029 
00030 using namespace srs_assisted_grasping;
00031 using namespace srs_assisted_grasping_msgs;
00032 
00033 
00034 bool ReactiveGrasping::readParams() {
00035 
00036   // read all parameters
00037   double tmp;
00038   ros::param::param<double>("~default_time", tmp, 3.0);
00039 
00040   params_.default_time = ros::Duration(tmp);
00041 
00042   ros::param::param<double>("~max_force", params_.max_force, 1000.0);
00043   ros::param::param<double>("~max_velocity", params_.max_velocity, 1.5);
00044   ros::param::param<double>("~a_ramp", params_.a_ramp, 10.0);
00045   ros::param::param<double>("~d_ramp", params_.d_ramp, 20.0);
00046   ros::param::param<double>("~rate", params_.rate, 20.0);
00047 
00048   // TODO add some checks for parameter values!!!
00049 
00050 
00051   ros::NodeHandle nh("~");
00052   XmlRpc::XmlRpcValue joints_list;
00053 
00054   joints_.num_of_tactile_pads = 0;
00055 
00056 
00057   if (nh.getParam("joints",joints_list)) {
00058 
00059           ROS_ASSERT(joints_list.getType() == XmlRpc::XmlRpcValue::TypeArray);
00060 
00061           for (int i=0; i < joints_list.size(); i++) {
00062 
00063                   XmlRpc::XmlRpcValue joint = joints_list[i];
00064 
00065                   if (joint.getType() != XmlRpc::XmlRpcValue::TypeStruct) {
00066 
00067                           ROS_ERROR("Wrong syntax in YAML config.");
00068                           return false;
00069 
00070                   }
00071 
00072                   if (!joint.hasMember("joint")) {
00073 
00074                           ROS_ERROR("Joint doesn't have 'joint' property defined.");
00075                           return false;
00076 
00077                   } else {
00078 
00079                           XmlRpc::XmlRpcValue joint_name = joint["joint"];
00080 
00081                           std::string tmp = static_cast<std::string>(joint_name);
00082 
00083                           joints_.joints.push_back(tmp);
00084 
00085                           std::cout << tmp << " ";
00086 
00087                   }
00088 
00089                   if (!joint.hasMember("static")) {
00090 
00091                                           ROS_WARN("Joint doesn't have 'static' property defined. Supposing true.");
00092 
00093                                           joints_.is_static.push_back(false);
00094 
00095                                   } else {
00096 
00097                           XmlRpc::XmlRpcValue static_joint = joint["static"];
00098 
00099                           bool tmp = static_cast<bool>(static_joint);
00100 
00101                           joints_.is_static.push_back(tmp);
00102 
00103                           std::cout << "static: " << tmp << " ";
00104                   }
00105 
00106                   if (!joint.hasMember("has_tactile_pad")) {
00107 
00108                           ROS_WARN("Joint doesn't have 'has_tactile_pad' property defined. Supposing false.");
00109 
00110                           joints_.has_tactile_pad.push_back(false);
00111 
00112                   } else {
00113 
00114                           XmlRpc::XmlRpcValue has_pad = joint["has_tactile_pad"];
00115 
00116                           bool tmp = static_cast<bool>(has_pad);
00117 
00118                           joints_.has_tactile_pad.push_back(tmp);
00119 
00120                           std::cout << "has_pad: " << tmp << std::endl;
00121 
00122                   }
00123 
00124           } // for
00125 
00126 
00127   } else {
00128 
00129           ROS_ERROR("Can't get list of joints!");
00130           return false;
00131 
00132   }
00133 
00134   for (unsigned char i=0; i < joints_.has_tactile_pad.size();i++) {
00135 
00136          if (joints_.has_tactile_pad[i]) joints_.num_of_tactile_pads++;
00137 
00138   }
00139 
00140   return true;
00141 
00142 }
00143 
00144 ReactiveGrasping::~ReactiveGrasping(void) {
00145 
00146       server_->shutdown();
00147       delete server_;
00148 
00149     };
00150 
00151 
00152 
00153 ReactiveGrasping::ReactiveGrasping(std::string name) {
00154 
00155   fatal_error_ = false;
00156 
00157   if (!readParams()) {
00158 
00159           fatal_error_ = true;
00160 
00161   } else {
00162 
00163           ROS_INFO("Configured for %d joints with %d tactile pads",(int)joints_.joints.size(),joints_.num_of_tactile_pads);
00164 
00165           feedback_data_.tactile_data.resize(joints_.num_of_tactile_pads);
00166           joints_.velocities.resize(joints_.joints.size());
00167           joints_.limits.resize(joints_.joints.size());
00168 
00169           feedback_data_.sdh_data_stamp = ros::Time(0);
00170           feedback_data_.tactile_data_stamp = ros::Time(0);
00171           feedback_data_.sdh_data_checked = false;
00172 
00173           server_ = new actionlib::SimpleActionServer<srs_assisted_grasping_msgs::ReactiveGraspingAction>(nh_, name, boost::bind(&ReactiveGrasping::execute, this, _1), false);
00174 
00175           sdh_mode_client_ = nh_.serviceClient<cob_srvs::SetOperationMode>("set_mode_srv");
00176 
00177           vel_publisher_ = nh_.advertise<brics_actuator::JointVelocities>("velocity_out", 10);
00178 
00179           action_name_ = name;
00180 
00181           time_to_stop_.resize(joints_.joints.size());
00182 
00183           tact_sub_  = nh_.subscribe("tact_in", 10, &ReactiveGrasping::TactileDataCallback,this);
00184           state_sub_ = nh_.subscribe("state_in", 10, &ReactiveGrasping::SdhStateCallback,this);
00185 
00186           urdf::Model model;
00187           model.initParam("robot_description");
00188 
00189           for (unsigned int i=0; i < joints_.joints.size(); i++) {
00190 
00191                   joints_.limits[i].min = model.getJoint(joints_.joints[i])->limits->lower;
00192                   joints_.limits[i].max = model.getJoint(joints_.joints[i])->limits->upper;
00193 
00194           }
00195 
00196 
00197           server_->start();
00198 
00199           ROS_INFO("Action server started");
00200 
00201   }
00202 
00203 }
00204 
00205 void ReactiveGrasping::stop() {
00206 
00207         ROS_INFO("Immediately stopping.");
00208 
00209         std::vector<double> vel;
00210         vel.resize(joints_.joints.size());
00211 
00212         for (unsigned int i=0; i < vel.size(); i++)
00213                 vel[i];
00214 
00215         publish(vel);
00216 
00217 }
00218 
00219 bool ReactiveGrasping::publish(std::vector<double> vel) {
00220 
00221         if (vel.size()!= joints_.joints.size()) {
00222 
00223                 ROS_ERROR("Error on publishing velocities - vector size mismatch.");
00224                 return false;
00225 
00226         }
00227 
00228 
00229         ros::Time now = ros::Time::now();
00230 
00231         brics_actuator::JointVelocities msg;
00232 
00233         for (unsigned int i=0; i < vel.size(); i++) {
00234 
00235                 brics_actuator::JointValue jv;
00236 
00237                 jv.timeStamp = now;
00238                 jv.joint_uri = joints_.joints[i];
00239                 jv.value = vel[i];
00240                 jv.unit = "rad/s";
00241 
00242         //std::cout << vel[i] << " ";
00243 
00244                 msg.velocities.push_back(jv);
00245 
00246         }
00247 
00248         //std::cout << std::endl;
00249 
00250         vel_publisher_.publish(msg);
00251 
00252         return true;
00253 
00254 }
00255 
00256 void ReactiveGrasping::execute(const ReactiveGraspingGoalConstPtr &goal) {
00257 
00258   ROS_INFO("Reactive grasping action triggered");
00259 
00260   joints_.velocities.clear();
00261 
00262   ReactiveGraspingResult res;
00263   ReactiveGraspingFeedback feedback;
00264 
00265   ros::Rate r(params_.rate);
00266 
00267   // check if we have data available
00268   bool data_received = false;
00269 
00270   feedback_data_.data_mutex.lock();
00271 
00272           if (feedback_data_.sdh_data_stamp > ros::Time(0) &&
00273                   feedback_data_.tactile_data_stamp > ros::Time(0)) data_received = true;
00274 
00275   feedback_data_.data_mutex.unlock();
00276 
00277   if (!data_received) {
00278 
00279           ROS_ERROR("SDH/tactile data not available! Could not perform action...");
00280 
00281           server_->setAborted(res,"no data received, could not perform action");
00282           return;
00283 
00284   }
00285 
00286   if (fatal_error_) {
00287 
00288           server_->setAborted(res,"Fatal error has occurred.");
00289           return;
00290 
00291   }
00292 
00293 
00294 
00295   bool limit_error = false;
00296 
00297   for(unsigned int i=0; i < joints_.joints.size(); i++) {
00298 
00299           if (joints_.is_static[i]) continue;
00300 
00301           double g = goal->target_configuration.data[i];
00302 
00303           if ( (g < joints_.limits[i].min) || (g > joints_.limits[i].max) ) {
00304 
00305                   ROS_ERROR("Target configuration for %s joint violates limits!",joints_.joints[i].c_str());
00306                   limit_error = true;
00307 
00308           }
00309 
00310     }
00311 
00312   if (limit_error) {
00313 
00314           server_->setAborted(res,"Target configuration out of limits.");
00315           return;
00316 
00317   }
00318 
00319   if (vel_publisher_.getNumSubscribers() == 0) {
00320 
00321           ROS_ERROR("No one is listening to our velocity commands!");
00322           server_->setAborted(res,"There is no listener.");
00323           return;
00324 
00325   }
00326 
00327   if (!setMode("velocity")) {
00328 
00329           server_->setAborted(res,"Could not set SDH to velocity mode.");
00330           return;
00331 
00332   }
00333 
00334   //limit_error = false;
00335 
00336   for(unsigned int i=0; i < joints_.joints.size(); i++) {
00337 
00338           if (joints_.is_static[i]) continue;
00339 
00340           double g = goal->target_configuration.data[i];
00341 
00342           if ( (g < joints_.limits[i].min) || (g > joints_.limits[i].max) ) {
00343 
00344                   ROS_ERROR("Target configuration for %s joint violates limits!",joints_.joints[i].c_str());
00345                   limit_error = true;
00346 
00347           }
00348 
00349     }
00350 
00351   if (limit_error) {
00352 
00353           server_->setAborted(res,"Target configuration out of limits.");
00354           return;
00355 
00356   }
00357 
00358   if (vel_publisher_.getNumSubscribers() == 0) {
00359 
00360           ROS_ERROR("No one is listening to our velocity commands!");
00361           server_->setAborted(res,"There is no listener.");
00362           return;
00363 
00364   }
00365 
00366   copyData();
00367 
00368   double t1 = goal->time.toSec() * (params_.a_ramp / 100.0);
00369   double t3 = goal->time.toSec() * (params_.d_ramp / 100.0);
00370   double t2 = goal->time.toSec() - (t1 + t3);
00371 
00372   ROS_INFO("t1=%f, t2=%f, t3=%f,tc=%f, rate=%f",t1,t2,t3,t1+t2+t3,params_.rate);
00373   ROS_INFO("Acc. will take %f %% of total time, dec. %f %%.",params_.a_ramp,params_.d_ramp);
00374 
00375   unsigned int num_of_acc = (unsigned int)ceil(t1 * params_.rate) - 1;
00376   unsigned int num_of_vel = (unsigned int)ceil(t2 * params_.rate);
00377   unsigned int num_of_dec = (unsigned int)ceil(t3 * params_.rate) - 1;
00378 
00379   bool velocity_limit_error = false;
00380 
00381   // compute velocities for all non-static joints
00382   for (unsigned int i = 0; i < joints_.joints.size(); i++) {
00383 
00384           if (joints_.is_static[i]) {
00385 
00386                   joints_.velocities[i].clear();
00387                   continue;
00388 
00389           } else {
00390 
00391 
00392                   double p1 = goal->target_configuration.data[i];
00393                   double p2 =  sdh_data_act_.positions[i];
00394 
00395                   double pos_diff = (p1-p2);
00396 
00397                   /*if (p1 <= 0 && p2 <= 0) pos_diff = fabs(p1 - p2);
00398                   if (p1 >= 0 && p2 >= 0) pos_diff = fabs(p1-p2);
00399                   if (p1 < 0 && p2 > 0) pos_diff = p2 - p1;
00400                   if (p1 > 0 && p2 < 0) pos_diff = p1 - p2;*/
00401 
00402                   //double pos_diff = (goal->target_configuration.data[i] - sdh_data_act_.positions[i]);
00403                   //double pos_diff = (sdh_data_act_.positions[i] - goal->target_configuration.data[i]);
00404 
00405                   double vel = (pos_diff / (0.5*t1 + t2 + 0.5*t3)); // constant velocity
00406                   double acc = (vel / t1) * (1.0 / params_.rate); // dv = a * dt = v/1 * 1/r
00407                   double dec = (vel / t3) * (1.0 / params_.rate);
00408 
00409                   if (fabs(vel) >= params_.max_velocity) {
00410 
00411                           ROS_WARN("Joint %s will violate max. velocity limit (%f, limit %f).",joints_.joints[i].c_str(),vel,params_.max_velocity);
00412 
00413                           velocity_limit_error = true;
00414 
00415                   }
00416 
00417                   ROS_INFO("Joint %d, dv1=%f (%u), v2=%f (%u), dv3=%f (%u), pos_diff: %f",i,acc,num_of_acc,vel,num_of_vel,dec,num_of_dec,pos_diff);
00418 
00419                   joints_.velocities[i].resize(num_of_acc + num_of_vel + num_of_dec);
00420 
00421                   joints_.velocities[i][0] = 0.0;
00422 
00423 
00424                   for (unsigned int j=1; j < (num_of_acc + num_of_vel + num_of_dec); j++) {
00425 
00426                           if (j < num_of_acc) {
00427 
00428                                   // acceleration
00429                                   joints_.velocities[i][j] = joints_.velocities[i][j-1] + acc;
00430 
00431                                   if (fabs(joints_.velocities[i][j]) > fabs(vel)) joints_.velocities[i][j] = vel;
00432 
00433 
00434 
00435                           } else if ( (j >= num_of_acc) && (j <= (num_of_acc + num_of_vel)) ) {
00436 
00437                                   // constant velocity
00438                                   joints_.velocities[i][j] = vel;
00439 
00440                           } else {
00441 
00442                                   // deceleration
00443                                   if ( fabs(joints_.velocities[i][j-1]) > fabs(dec) ) {
00444 
00445                                         joints_.velocities[i][j] = joints_.velocities[i][j-1] - dec;
00446 
00447                                  } else {
00448 
00449                                          joints_.velocities[i][j] = 0.0;
00450 
00451                                  }
00452 
00453                           } // deceleration
00454 
00455                           //std::cout << joints_.velocities[i][j] << " ";
00456 
00457                   } // for num of vel
00458 
00459           } // else
00460 
00461           //std::cout << std::endl  << std::endl;
00462 
00463   }
00464 
00465   if (velocity_limit_error) {
00466 
00467           server_->setAborted(res,"Some joint hit velocity limit.");
00468           return;
00469 
00470   }
00471 
00472   for(unsigned int i=0; i < joints_.joints.size(); i++) {
00473 
00474           time_to_stop_[i] = -1.0;
00475 
00476   }
00477 
00478   ros::Time start_time = ros::Time::now();
00479   ros::Time max_time = ros::Time(0);
00480 
00481   if ( goal->time > ros::Duration(0) ) max_time = start_time + goal->time;
00482   else max_time = start_time + params_.default_time;
00483 
00484   unsigned int iter = 0;
00485 
00486   while(ros::ok()) {
00487 
00488           // check for preempt request
00489           if (server_->isPreemptRequested()) {
00490 
00491                  ros::Duration time_elapsed = ros::Time::now() - start_time;
00492                  double time_elapsed_d = time_elapsed.toSec();
00493 
00494                  ROS_INFO("%s: Preempted, elapsed time: %f", action_name_.c_str(),time_elapsed_d);
00495 
00496                  server_->setPreempted(res,std::string("preempted"));
00497 
00498                  stop();
00499 
00500                  setMode("position");
00501 
00502                  return;
00503 
00504               }
00505 
00506           // check for time condition
00507           if ((ros::Time::now() >= max_time) || iter >= (num_of_acc + num_of_vel + num_of_dec) ) {
00508 
00509                   ros::Duration time_elapsed = ros::Time::now() - start_time;
00510                   double time_elapsed_d = time_elapsed.toSec();
00511 
00512                   ROS_INFO("Max. time condition reached (%fs, iter: %u)!",time_elapsed_d,iter);
00513 
00514                   res.actual_forces.data = tactile_data_;
00515 
00516 
00517                   res.actual_joint_values.data.resize(sdh_data_act_.positions.size());
00518                   for (unsigned int i=0; i < sdh_data_act_.positions.size(); i++) {
00519 
00520                           res.actual_joint_values.data[i] = (float)sdh_data_act_.positions[i];
00521 
00522                   }
00523 
00524                   ros::Duration d = ros::Time::now() - start_time;
00525 
00526                   for (unsigned int i=0; i < time_to_stop_.size(); i++) {
00527 
00528                           if (time_to_stop_[i] == -1.0) time_to_stop_[i] = d.toSec();
00529 
00530                   }
00531 
00532                   res.time_to_stop.data = time_to_stop_;
00533 
00534                   server_->setSucceeded(res,"Max. time condition reached.");
00535 
00536                   stop();
00537 
00538                   setMode("position");
00539 
00540                   return;
00541 
00542           }
00543 
00544           copyData();
00545 
00546           // array for velocities
00547           std::vector<double> vel;
00548           vel.resize(joints_.joints.size());
00549 
00550           // tdb
00551           if (iter++ < (num_of_acc + num_of_vel + num_of_dec) ) {
00552 
00553                   // for each joint, assign correct velocity here
00554                   for(unsigned int i=0; i < joints_.joints.size(); i++) {
00555 
00556                           vel[i] = 0.0;
00557 
00558                           // skip static joints
00559                           if (joints_.is_static[i]) continue;
00560 
00561                           // skip joints which already reached their configuration
00562                           if (fabs(sdh_data_act_.positions[i] - goal->target_configuration.data[i]) < 0.02) {
00563 
00564                                   if (time_to_stop_[i] == -1.0) {
00565 
00566                                           ros::Duration d = ros::Time::now() - start_time;
00567                                           time_to_stop_[i] = d.toSec();
00568 
00569                                           ROS_INFO("Joint %s (%u) reached target configuration in %f secs.",joints_.joints[i].c_str(),i,time_to_stop_[i]);
00570 
00571                                   }
00572 
00573                                   continue;
00574 
00575                           }
00576 
00577                           // test force only for joints with tactile pad
00578                           if (joints_.has_tactile_pad[i]) {
00579 
00580                                   if (tactile_data_[i] >= goal->max_force.data[i]) {
00581 
00582                                           if (time_to_stop_[i] == -1.0) {
00583 
00584                                                   ros::Duration d = ros::Time::now() - start_time;
00585                                                   time_to_stop_[i] = d.toSec();
00586 
00587                                                   ROS_INFO("Joint %s (%u) reached max. force (%d) in %f secs.",joints_.joints[i].c_str(),i,tactile_data_[i],time_to_stop_[i]);
00588 
00589                                           }
00590 
00591                                           continue;
00592 
00593                                   } else vel[i] = joints_.velocities[i][iter];
00594 
00595 
00596                           } else vel[i] = joints_.velocities[i][iter];
00597 
00598 
00599 
00600                   } // for over all joints
00601 
00602                   //iter++;
00603 
00604           }
00605 
00606           // publish velocities
00607           publish(vel);
00608 
00609           r.sleep();
00610 
00611   } // while
00612 
00613 
00614 }
00615 
00616 void ReactiveGrasping::copyData() {
00617 
00618   // make copy of feedback data which is not accessed from callbacks
00619   feedback_data_.data_mutex.lock();
00620 
00621   sdh_data_act_ = feedback_data_.sdh_data.actual;
00622   tactile_data_ = feedback_data_.tactile_data;
00623 
00624   feedback_data_.data_mutex.unlock();
00625 
00626 }
00627 
00628 void ReactiveGrasping::SdhStateCallback(const pr2_controllers_msgs::JointTrajectoryControllerState::ConstPtr & msg) {
00629 
00630   if (fatal_error_) return;
00631 
00632   boost::mutex::scoped_lock(feedback_data_.data_mutex);
00633 
00634   feedback_data_.sdh_data = *msg;
00635 
00636   feedback_data_.sdh_data_stamp = ros::Time::now();
00637 
00638   if (!feedback_data_.sdh_data_checked) {
00639 
00640           // check sizes of lists
00641           if (feedback_data_.sdh_data.joint_names.size() != joints_.joints.size()) {
00642 
00643                   ROS_ERROR_ONCE("Received data for more/less joints than configured!");
00644                   fatal_error_ = true;
00645                   return;
00646 
00647           }
00648 
00649           // check names of joints and order
00650           for (unsigned int i=0; i<joints_.joints.size(); i++) {
00651 
00652                   if (joints_.joints[i] != feedback_data_.sdh_data.joint_names[i]) {
00653 
00654                           ROS_ERROR_ONCE("Order or names of joint differs in config and received data!");
00655                           fatal_error_ = true;
00656                           return;
00657 
00658                   }
00659 
00660           } // for
00661 
00662           feedback_data_.sdh_data_checked = true;
00663 
00664   }
00665 
00666 }
00667 
00668 
00669 void ReactiveGrasping::TactileDataCallback(const schunk_sdh::TactileSensor::ConstPtr& msg) {
00670 
00671   if (fatal_error_) return;
00672 
00673   boost::mutex::scoped_lock(feedback_data_.data_mutex);
00674 
00675   //feedback_data_.tactile_data = *msg;
00676 
00677   feedback_data_.tactile_data_stamp = ros::Time::now();
00678 
00679   if (! feedback_data_.tactile_data_checked) {
00680 
00681           if (msg->tactile_matrix.size() != (unsigned int)joints_.num_of_tactile_pads) {
00682 
00683                 ROS_ERROR("Received amount of tactile matrixes (%u) differs from configuration (%u)!",
00684                                 (unsigned int)joints_.num_of_tactile_pads,
00685                                 (unsigned int)feedback_data_.tactile_data.size());
00686 
00687                 fatal_error_ = true;
00688                 return;
00689 
00690           }
00691 
00692           feedback_data_.tactile_data_checked = true;
00693   }
00694 
00695   // for each pad find the maximum value
00696   for(unsigned int i=0; i < feedback_data_.tactile_data.size(); i++) {
00697 
00698           int16_t max = 0;
00699 
00700           for (unsigned int j=0; j < (unsigned int)(msg->tactile_matrix[i].cells_x*msg->tactile_matrix[i].cells_y); j++) {
00701 
00702                   if ( (msg->tactile_matrix[i].tactile_array[j] > max) && (msg->tactile_matrix[i].tactile_array[j] < 20000) ) max = msg->tactile_matrix[i].tactile_array[j];
00703 
00704           }
00705 
00706           feedback_data_.tactile_data[i] = max;
00707 
00708   }
00709 
00710 }
00711 
00712 
00713 bool ReactiveGrasping::setMode(std::string mode) {
00714 
00715 
00716         cob_srvs::SetOperationMode srv;
00717 
00718         srv.request.operation_mode.data = mode;
00719 
00720         if (sdh_mode_client_.call(srv)) {
00721 
00722                 if (srv.response.success.data) {
00723 
00724                         ROS_INFO("SDH should be in %s mode",mode.c_str());
00725                         return true;
00726 
00727                 } else {
00728 
00729                         ROS_ERROR("Failed to set SDH to %s mode, error: %s",mode.c_str(),srv.response.error_message.data.c_str());
00730                         return false;
00731 
00732                 }
00733 
00734           } else {
00735 
00736                   ROS_ERROR("Failed to call SDH mode service");
00737                   return false;
00738 
00739           }
00740 
00741 }
00742 
00743 int main(int argc, char** argv)
00744 {
00745 
00746 
00747       ROS_INFO("Starting reactive grasping node");
00748       ros::init(argc, argv, "but_reactive_grasping_node");
00749 
00750       std::string tmp = ACT_GRASP;
00751 
00752       ReactiveGrasping mg(tmp);
00753 
00754 
00755       ROS_INFO("Spinning...");
00756 
00757       ros::spin();
00758       ros::shutdown();
00759 
00760 }


srs_assisted_grasping
Author(s): Zdenek Materna
autogenerated on Mon Oct 6 2014 07:59:09