00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00049
00050
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
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
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
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 }
00157
00158
00159
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 }
00190
00191
00192
00193
00194 presets_.push_back(pr);
00195
00196 }
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
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
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
00317
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
00327
00328 vsizer_glob->SetSizeHints(this);
00329 this->SetSizerAndFit(vsizer_glob);
00330
00331 as_client_ = new grasping_action_client(ACT_GRASP,true);
00332
00333
00334
00335 tactile_data_received_ = false;
00336
00337 stop_gui_thread_ = false;
00338
00339 t_gui_update = boost::thread(&CButGraspingControls::GuiUpdateThread,this);
00340
00341
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
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
00434
00435
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
00488
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
00500
00501 uint16_t i=0;
00502
00503 ros::Duration dur(1);
00504
00505
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
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
00614 DisableControls(true);
00615
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
00625
00626
00627
00628
00629
00630
00631
00632
00633
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
00655
00656
00657
00658
00659
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
00673 EnableControls();
00674
00675
00676 grasping_allowed_ = true;
00677
00678 } else {
00679
00680 ROS_INFO("Grasping: disabling controls.");
00681
00682
00683 DisableControls();
00684
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