grasping_controls.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: 5/4/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_ui/grasping_controls.h>
00029 
00030 #include <rviz/window_manager_interface.h>
00031 
00032 using namespace std;
00033 using namespace srs_assisted_grasping_ui;
00034 using namespace srs_assisted_grasping_msgs;
00035 using namespace srs_assisted_grasping;
00036 
00037 const int ID_BUTTON_GRASP(101);
00038 const int ID_BUTTON_STOP(102);
00039 const int ID_SLIDER_FORCE(104);
00040 
00041 const int ID_CHOICE(115);
00042 
00043 const int ID_SLIDER_FORCE_1(105);
00044 const int ID_SLIDER_FORCE_2(106);
00045 const int ID_SLIDER_FORCE_3(107);
00046 
00047 /*
00048  * TODO
00049  *
00050  *  - add groups "Object grasping", "Force feedback"
00051  *
00052  */
00053 
00057 CButGraspingControls::CButGraspingControls(wxWindow *parent, const wxString& title, rviz::WindowManagerInterface * wmi )
00058     : wxPanel( parent, wxID_ANY, wxDefaultPosition, wxSize(280, 180), wxTAB_TRAVERSAL, title)
00059     , m_wmi( wmi )
00060 {
00061 
00062     parent_ = parent;
00063 
00064     ros::NodeHandle nh("~");
00065 
00066     ros::param::param<double>("~abs_max_force", abs_max_force_ , ABS_MAX_FORCE);
00067     ros::param::param<bool>("~wait_for_allow", wait_for_allow_ , WAIT_FOR_ALLOW);
00068 
00069     XmlRpc::XmlRpcValue pres;
00070 
00071     if (nh.getParam("grasping_presets",pres)) {
00072 
00073         ROS_ASSERT(pres.getType() == XmlRpc::XmlRpcValue::TypeArray);
00074 
00075         ROS_INFO("%d presets for assisted grasping plugin.",pres.size());
00076 
00077         for (int i=0; i < pres.size(); i++) {
00078 
00079                 Preset pr;
00080 
00081                 XmlRpc::XmlRpcValue xpr = pres[i];
00082 
00083                         if (xpr.getType() != XmlRpc::XmlRpcValue::TypeStruct) {
00084 
00085                           ROS_ERROR("Wrong syntax in YAML config.");
00086                           continue;
00087 
00088                         }
00089 
00090                         // read the name
00091                         if (!xpr.hasMember("name")) {
00092 
00093                           ROS_ERROR("Preset doesn't have 'name' property defined.");
00094                           continue;
00095 
00096                         } else {
00097 
00098                           XmlRpc::XmlRpcValue name = xpr["name"];
00099 
00100                           std::string tmp = static_cast<std::string>(name);
00101 
00102                           pr.name = tmp;
00103 
00104                           std::cout << tmp << " ";
00105 
00106                         }
00107 
00108                         // read the time
00109                         if (!xpr.hasMember("time")) {
00110 
00111                           ROS_ERROR("Preset doesn't have 'time' property defined.");
00112                           continue;
00113 
00114                         } else {
00115 
00116                           XmlRpc::XmlRpcValue time = xpr["time"];
00117 
00118                           double tmp = static_cast<double>(time);
00119 
00120                           pr.time = ros::Duration(tmp);
00121 
00122                           std::cout << tmp << " ";
00123 
00124                         }
00125 
00126                         // read the forces
00127                         if (!xpr.hasMember("forces")) {
00128 
00129                           ROS_ERROR("Preset doesn't have 'forces' property defined.");
00130                           continue;
00131 
00132                         } else {
00133 
00134                           XmlRpc::XmlRpcValue forces = xpr["forces"];
00135 
00136                           if (forces.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00137 
00138                                   for (int i=0; i < forces.size(); i++) {
00139 
00140                                           XmlRpc::XmlRpcValue f = forces[i];
00141 
00142                                           double tmp = static_cast<double>(f);
00143 
00144                                           pr.forces.push_back(tmp);
00145 
00146                                   }
00147 
00148 
00149                           } else {
00150 
00151                                   ROS_ERROR("Property 'forces' is defined in bad way.");
00152                                   continue;
00153 
00154                           }
00155 
00156                         } // else forces
00157 
00158 
00159                         // read the positions
00160                         if (!xpr.hasMember("target_pos")) {
00161 
00162                           ROS_ERROR("Preset doesn't have 'target_pos' property defined.");
00163                           continue;
00164 
00165                         } else {
00166 
00167                           XmlRpc::XmlRpcValue target_pos = xpr["target_pos"];
00168 
00169                           if (target_pos.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00170 
00171                                   for (int i=0; i < target_pos.size(); i++) {
00172 
00173                                           XmlRpc::XmlRpcValue p = target_pos[i];
00174 
00175                                           double tmp = static_cast<double>(p);
00176 
00177                                           pr.target_pos.push_back(tmp);
00178 
00179                                   }
00180 
00181 
00182                           } else {
00183 
00184                                   ROS_ERROR("Property 'target_pos' is defined in bad way.");
00185                                   continue;
00186 
00187                           }
00188 
00189                         } // else target_pos
00190 
00191 
00192                         // TODO test number of forces / positions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00193 
00194                         presets_.push_back(pr);
00195 
00196         } // for around all presets
00197 
00198 
00199 
00200     } else {
00201 
00202         ROS_ERROR("Could not get presets for grasping, using defaults.");
00203 
00204         Preset pr;
00205                 pr.name = "Empty bottle";
00206                 pr.forces.resize(6);
00207 
00208                 for(int i=0; i < 6; i++) pr.forces[i] = 300.0;
00209 
00210                 pr.target_pos.resize(7);
00211 
00212                 pr.target_pos[0] = 0.0;
00213                 pr.target_pos[1] = 0.0;
00214                 pr.target_pos[2] = 1.0472;
00215                 pr.target_pos[3] = 0.0;
00216                 pr.target_pos[4] = 1.0472;
00217                 pr.target_pos[5] = 0.0;
00218                 pr.target_pos[6] = 1.0472;
00219 
00220                 pr.time = ros::Duration(5.0);
00221 
00222                 presets_.push_back(pr);
00223 
00224     }
00225 
00226 
00227     wxArrayString prt;
00228 
00229     for(unsigned int i=0; i < presets_.size(); i++)
00230         prt.Add(wxString::FromAscii(presets_[i].name.c_str()));
00231 
00232     presets_choice_ = new wxChoice(this, ID_CHOICE,wxDefaultPosition,wxDefaultSize,prt);
00233 
00234     buttons_["grasp"] = new wxButton(this, ID_BUTTON_GRASP, wxT("Grasp"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00235     buttons_["stop"] = new wxButton(this, ID_BUTTON_STOP, wxT("Stop"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00236 
00237     buttons_["stop"]->SetForegroundColour (wxColour (255, 255, 255));
00238     buttons_["stop"]->SetBackgroundColour (wxColour (255, 108, 108));
00239 
00240     m_text_status_ = new wxStaticText(this, -1, wxT("status: idle"));
00241 
00242     stringstream ss (stringstream::in | stringstream::out);
00243 
00244 
00245 
00246     std::vector<double> f = presets_[presets_choice_->GetSelection()].forces;
00247 
00248     double max_f = 0.0;
00249 
00250     for(unsigned int i=0; i < f.size(); i++) {
00251 
00252         if (f[i] > max_f) max_f = f[i];
00253 
00254     }
00255 
00256     m_text_max_force_ = new wxStaticText(this, -1, wxT("Maximum force"));
00257 
00258     max_force_slider_ = new wxSlider(this,ID_SLIDER_FORCE,(int)max_f,0,abs_max_force_,wxDefaultPosition,wxDefaultSize,wxSL_LABELS);
00259     max_force_slider_->Enable(false);
00260 
00261 
00262     finger1_force_slider_ = new wxSlider(this,ID_SLIDER_FORCE_1,0.0,0,abs_max_force_);
00263     finger2_force_slider_ = new wxSlider(this,ID_SLIDER_FORCE_2,0.0,0,abs_max_force_);
00264     finger3_force_slider_ = new wxSlider(this,ID_SLIDER_FORCE_3,0.0,0,abs_max_force_);
00265 
00266     tactile_data_.resize(6);
00267 
00268     wxSizer *hsizer_buttons = new wxBoxSizer(wxHORIZONTAL);
00269 
00270     wxSizer *vsizer_glob = new wxBoxSizer(wxVERTICAL);
00271 
00272     hsizer_buttons->Add(buttons_["grasp"], ID_BUTTON_GRASP);
00273     hsizer_buttons->Add(buttons_["stop"], ID_BUTTON_STOP);
00274 
00275     //wxSizer *vsizer = new wxBoxSizer(wxVERTICAL); // top sizer
00276     wxSizer *vsizer_top = new wxStaticBoxSizer(wxVERTICAL,this,wxT("Object grasping"));
00277 
00278     vsizer_top->Add(hsizer_buttons,1,wxEXPAND);
00279 
00280 
00281     vsizer_top->Add(m_text_status_);
00282     vsizer_top->Add(presets_choice_);
00283 
00284     vsizer_top->Add(m_text_max_force_);
00285     vsizer_top->Add(max_force_slider_,1,wxEXPAND);
00286 
00287 
00288 
00289     wxSizer *vsizer_sliders = new wxStaticBoxSizer(wxVERTICAL,this,wxT("Force feedback"));
00290 
00291 
00292     vsizer_sliders->Add(finger1_force_slider_,1,wxEXPAND);
00293     vsizer_sliders->Add(finger2_force_slider_,1,wxEXPAND);
00294     vsizer_sliders->Add(finger3_force_slider_,1,wxEXPAND);
00295 
00296     //vsizer->Add(vsizer_sliders,1,wxEXPAND);
00297 
00298 
00299     finger1_force_slider_->Enable(false);
00300     finger2_force_slider_->Enable(false);
00301     finger3_force_slider_->Enable(false);
00302 
00303     setButton("stop",false);
00304 
00305     grasping_allowed_ = false;
00306 
00307     if (wait_for_allow_) {
00308 
00309         DisableControls();
00310 
00311     } else {
00312 
00313         EnableControls();
00314     }
00315 
00316     /*Connect(ID_SLIDER_FORCE, wxEVT_SCROLL_THUMBRELEASE,
00317               wxCommandEventHandler(CButGraspingControls::OnMaxForceSlider));*/
00318 
00319     Connect(ID_CHOICE, wxEVT_COMMAND_CHOICE_SELECTED,
00320                   wxCommandEventHandler(CButGraspingControls::OnChoice));
00321 
00322     vsizer_glob->Add(vsizer_top,1,wxEXPAND|wxHORIZONTAL);
00323     vsizer_glob->Add(vsizer_sliders,1,wxEXPAND|wxHORIZONTAL);
00324 
00325 
00326     //this->SetSizerAndFit(vsizer_top);
00327 
00328     vsizer_glob->SetSizeHints(this);
00329     this->SetSizerAndFit(vsizer_glob);
00330 
00331     as_client_ = new grasping_action_client(ACT_GRASP,true);
00332 
00333     //ros::NodeHandle nh;
00334 
00335     tactile_data_received_ = false;
00336 
00337     stop_gui_thread_ = false;
00338 
00339     t_gui_update = boost::thread(&CButGraspingControls::GuiUpdateThread,this);
00340 
00341     //gui_update_timer_ = nh.createTimer(ros::Duration(0.5),&CButGraspingControls::timerCallback,this);
00342     tact_sub_  = nh.subscribe("/dsa_controller/tactile_data_filtered", 10, &CButGraspingControls::TactileDataCallback,this);
00343 
00344     service_grasping_allow_ = nh.advertiseService(SRV_ALLOW,&CButGraspingControls::GraspingAllow,this);
00345 
00346 
00347 }
00348 
00349 void CButGraspingControls::GuiUpdateThread() {
00350 
00351         ROS_INFO("Grasping GUI thread started.");
00352 
00353         ros::Rate r(10);
00354 
00355         while(!stop_gui_thread_) {
00356 
00357                 if (tactile_data_received_) {
00358 
00359                         std::vector<int16_t> tmp;
00360 
00361                         tactile_data_mutex_.lock();
00362 
00363                         tmp = tactile_data_;
00364 
00365                         tactile_data_mutex_.unlock();
00366 
00367                         wxMutexGuiEnter();
00368 
00369                         if (tmp[0] > tmp[1] ) finger1_force_slider_->SetValue(tmp[0]);
00370                         else finger1_force_slider_->SetValue(tmp[1]);
00371 
00372                         if (tmp[2] > tmp[3] ) finger2_force_slider_->SetValue(tmp[2]);
00373                         else finger2_force_slider_->SetValue(tmp[3]);
00374 
00375                         if (tmp[4] > tmp[5] ) finger3_force_slider_->SetValue(tmp[4]);
00376                         else finger3_force_slider_->SetValue(tmp[5]);
00377 
00378                         wxMutexGuiLeave();
00379 
00380                 }
00381 
00382                 r.sleep();
00383 
00384         }
00385 
00386         stop_gui_thread_ = false;
00387 
00388 
00389 }
00390 
00391 void CButGraspingControls::TactileDataCallback(const schunk_sdh::TactileSensor::ConstPtr& msg) {
00392 
00393   ROS_INFO_ONCE("Tactile data received.");
00394 
00395   tactile_data_mutex_.lock();
00396 
00397   // for each pad find the maximum value
00398   for(unsigned int i=0; i < 6; i++) {
00399 
00400           int16_t max = 0;
00401 
00402           for (unsigned int j=0; j < (unsigned int)(msg->tactile_matrix[i].cells_x*msg->tactile_matrix[i].cells_y); j++) {
00403 
00404                   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];
00405 
00406           }
00407 
00408           tactile_data_[i] = max;
00409 
00410   }
00411 
00412   tactile_data_received_ = true;
00413 
00414   tactile_data_mutex_.unlock();
00415 
00416 
00417 }
00418 
00419 
00420 
00421 void CButGraspingControls::setButton(string but, bool state) {
00422 
00423   if (buttons_[but]!=NULL)
00424     buttons_[but]->Enable(state);
00425 
00426 }
00427 
00428 
00429 CButGraspingControls::~CButGraspingControls() {
00430 
00431   stop_gui_thread_ = true;
00432 
00433   /*ros::Rate r(0.1);
00434 
00435   while(stop_gui_thread_ == true) r.sleep();*/
00436 
00437   ROS_INFO("Waiting for threads to finish.");
00438 
00439   t_gui_update.join();
00440 
00441   ButtonsMap::iterator it;
00442 
00443     for (it = buttons_.begin(); it != buttons_.end(); ++it)
00444       delete it->second;
00445 
00446     buttons_.clear();
00447 
00448     delete as_client_;
00449 
00450     ROS_INFO("Exiting...");
00451 
00452 }
00453 
00454 
00455 void CButGraspingControls::GraspingThread() {
00456 
00457   ROS_INFO("Let's start grasping...");
00458 
00459   if (!as_client_->waitForServer(ros::Duration(3.0))) {
00460 
00461     ROS_ERROR("Grasping action server not running!");
00462 
00463     wxMutexGuiEnter();
00464     m_text_status_->SetLabel(wxString::FromAscii("status: Communication error."));
00465 
00466     EnableControls();
00467 
00468     wxMutexGuiLeave();
00469 
00470     return;
00471 
00472   }
00473 
00474   int choice = presets_choice_->GetSelection();
00475 
00476   ReactiveGraspingGoal goal;
00477 
00478   goal.target_configuration.data.resize(presets_[choice].target_pos.size());
00479   goal.max_force.data.resize(presets_[choice].forces.size());
00480 
00481   for (unsigned int i=0; i < presets_[choice].target_pos.size(); i++)
00482           goal.target_configuration.data[i] = presets_[choice].target_pos[i];
00483 
00484   for (unsigned int i=0; i < presets_[choice].forces.size(); i++)
00485           goal.max_force.data[i] = presets_[choice].forces[i];
00486 
00487   //goal.target_configuration.data = presets_[choice].target_pos;
00488   //goal.max_force.data = presets_[choice].forces;
00489 
00490   goal.time = presets_[choice].time;
00491 
00492   grasping_finished_ = false;
00493 
00494   as_client_->sendGoal(goal,
00495                   boost::bind(&CButGraspingControls::GraspingDone, this, _1, _2),
00496                   boost::bind(&CButGraspingControls::GraspingActive, this));
00497 
00498 
00499   // TODO timeout!!!!!!!!!!!!!! treat case if action fails.....
00500 
00501   uint16_t i=0;
00502 
00503   ros::Duration dur(1);
00504 
00505   // wait for 60 seconds
00506   while( (i < 60) && (!grasping_finished_) ) {
00507 
00508           dur.sleep();
00509 
00510   }
00511 
00512   if (!grasping_finished_) {
00513 
00514           ROS_ERROR("Manual grasping action timeouted.");
00515 
00516           wxMutexGuiEnter();
00517           m_text_status_->SetLabel(wxString::FromAscii("status: Timeout."));
00518 
00519           setButton("stop",false);
00520 
00521           if (grasping_allowed_ || !wait_for_allow_) {
00522 
00523                   EnableControls();
00524 
00525           }
00526 
00527           wxMutexGuiLeave();
00528 
00529           as_client_->cancelAllGoals();
00530 
00531   }
00532 
00533   return;
00534 
00535 
00536 }
00537 
00538 
00539 void CButGraspingControls::GraspingDone(const actionlib::SimpleClientGoalState& state,
00540                                           const ReactiveGraspingResultConstPtr& result) {
00541 
00542         ROS_INFO("Grasping action finished...");
00543 
00544         grasping_finished_ = true;
00545 
00546         wxMutexGuiEnter();
00547 
00548           if (state == actionlib::SimpleClientGoalState::SUCCEEDED) {
00549 
00550 
00551             ROS_INFO("Object should be now grasped.");
00552             m_text_status_->SetLabel(wxString::FromAscii("status: Grasping completed."));
00553 
00554           } else {
00555 
00556             ROS_ERROR("Grasping failed.");
00557             m_text_status_->SetLabel(wxString::FromAscii("status: Grasping failed."));
00558 
00559           }
00560 
00561           if (grasping_allowed_ || !wait_for_allow_) {
00562 
00563                   EnableControls();
00564 
00565               }
00566 
00567           setButton("stop",false);
00568 
00569           wxMutexGuiLeave();
00570 
00571 }
00572 
00573 void CButGraspingControls::OnStop(wxCommandEvent& event) {
00574 
00575   as_client_->cancelAllGoals();
00576 
00577   DisableControls(false);
00578 
00579   if (grasping_allowed_ || !wait_for_allow_) {
00580 
00581           EnableControls();
00582 
00583   }
00584 
00585 }
00586 
00587 void CButGraspingControls::EnableControls() {
00588 
00589         setButton("grasp",true);
00590         setButton("stop",false);
00591         //max_force_slider_->Enable(true);
00592 
00593 
00594 }
00595 
00596 void CButGraspingControls::DisableControls(bool state_of_stop_button) {
00597 
00598         setButton("grasp",false);
00599         setButton("stop",state_of_stop_button);
00600 
00601 
00602 }
00603 
00604 void CButGraspingControls::OnGrasp(wxCommandEvent& event) {
00605 
00606   boost::posix_time::time_duration td = boost::posix_time::milliseconds(100);
00607 
00609   if (t_grasping.timed_join(td)) {
00610 
00611     m_text_status_->SetLabel(wxString::FromAscii("status: Trying to grasp. Please wait..."));
00612 
00613     //wxMutexGuiEnter();
00614     DisableControls(true);
00615     //wxMutexGuiLeave();
00616 
00617     t_grasping = boost::thread(&CButGraspingControls::GraspingThread,this);
00618 
00619   } else ROS_INFO("We have to wait until GRASPING thread finishes.");
00620 
00621 
00622 }
00623 
00624 /*void CButGraspingControls::OnMaxForceSlider(wxCommandEvent& event) {
00625 
00626   stringstream ss (stringstream::in | stringstream::out);
00627 
00628   ss << "max. force: ";
00629   ss << (double)max_force_slider_->GetValue();
00630 
00631   string tmp = ss.str();
00632 
00633   m_text_max_force_->SetLabel(wxString::FromAscii(tmp.c_str()));
00634 
00635 
00636 }*/
00637 
00638 void CButGraspingControls::OnChoice(wxCommandEvent& event) {
00639 
00640   stringstream ss (stringstream::in | stringstream::out);
00641 
00642   int choice = presets_choice_->GetSelection();
00643 
00644   ss << "max. force: ";
00645 
00646   double max_f = 0.0;
00647 
00648   for (unsigned i=0; i < presets_[choice].forces.size();i++) {
00649 
00650           if (presets_[choice].forces[i] > max_f) max_f = presets_[choice].forces[i];
00651 
00652   }
00653 
00654   //ss << (double)max_force_slider_->GetValue();
00655   /*ss << (double)max_f;
00656 
00657   string tmp = ss.str();
00658 
00659   m_text_max_force_->SetLabel(wxString::FromAscii(tmp.c_str()));*/
00660 
00661   max_force_slider_->SetValue((int)max_f);
00662 
00663 }
00664 
00665 bool CButGraspingControls::GraspingAllow(GraspingAllow::Request &req, GraspingAllow::Response &res) {
00666 
00667 
00668         if (req.allow) {
00669 
00670                 ROS_INFO("Grasping: enabling controls.");
00671 
00672                 //wxMutexGuiEnter();
00673                 EnableControls();
00674                 //wxMutexGuiLeave();
00675 
00676                 grasping_allowed_ = true;
00677 
00678         } else {
00679 
00680                 ROS_INFO("Grasping: disabling controls.");
00681 
00682                 //wxMutexGuiEnter();
00683                 DisableControls();
00684                 //wxMutexGuiLeave();
00685 
00686                 grasping_allowed_ = false;
00687 
00688         }
00689 
00690 
00691         return true;
00692 
00693 }
00694 
00695 
00696 BEGIN_EVENT_TABLE(CButGraspingControls, wxPanel)
00697     EVT_BUTTON(ID_BUTTON_GRASP,  CButGraspingControls::OnGrasp)
00698     EVT_BUTTON(ID_BUTTON_STOP,  CButGraspingControls::OnStop)
00699 END_EVENT_TABLE()
00700 


srs_assisted_grasping_ui
Author(s): Zdenek Materna
autogenerated on Mon Oct 6 2014 08:42:56