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
00036 #include "srs_assisted_arm_navigation_ui/arm_navigation_controls.h"
00037
00038 #include <rviz/window_manager_interface.h>
00039
00040 using namespace std;
00041 using namespace srs_assisted_arm_navigation_ui;
00042 using namespace srs_assisted_arm_navigation;
00043 using namespace srs_assisted_arm_navigation_msgs;
00044
00045 const int ID_BUTTON_NEW(101);
00046 const int ID_BUTTON_PLAN(102);
00047
00048 const int ID_BUTTON_EXECUTE(104);
00049 const int ID_BUTTON_RESET(105);
00050 const int ID_BUTTON_SUCCESS(106);
00051 const int ID_BUTTON_FAILED(107);
00052
00053
00054
00055 const int ID_BUTTON_REPEAT(114);
00056
00057 const int ID_BUTTON_UNDO(115);
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 const int ID_CHECKBOX_POS(125);
00071 const int ID_CHECKBOX_OR(126);
00072
00073 const int ID_CHECKBOX_ACO(120);
00074
00075
00076 const int ID_BUTTON_STOP_TRAJ(123);
00077
00078 const int ID_CHOICE(175);
00079
00083 CArmManipulationControls::CArmManipulationControls(wxWindow *parent, const wxString& title, rviz::WindowManagerInterface * wmi )
00084 : wxPanel( parent, wxID_ANY, wxDefaultPosition, wxSize(280, 180), wxTAB_TRAVERSAL, title)
00085 , m_wmi( wmi )
00086 {
00087
00088
00089 parent_ = parent;
00090
00091 traj_executed_ = 0;
00092
00093 ros::param::param<bool>("~wait_for_start", wait_for_start_ , WAIT_FOR_START);
00094
00095 ros::NodeHandle nh("~");
00096
00097 XmlRpc::XmlRpcValue pres;
00098
00099 if (nh.getParam("arm_nav_presets",pres)) {
00100
00101 ROS_ASSERT(pres.getType() == XmlRpc::XmlRpcValue::TypeArray);
00102
00103 ROS_INFO("%d presets for assisted arm navigation plugin.",pres.size());
00104
00105 for (int i=0; i < pres.size(); i++) {
00106
00107 Preset pr;
00108
00109 XmlRpc::XmlRpcValue xpr = pres[i];
00110
00111 if (xpr.getType() != XmlRpc::XmlRpcValue::TypeStruct) {
00112
00113 ROS_ERROR("Wrong syntax in YAML config.");
00114 continue;
00115
00116 }
00117
00118
00119 if (!xpr.hasMember("name")) {
00120
00121 ROS_ERROR("Preset doesn't have 'name' property defined.");
00122 continue;
00123
00124 } else {
00125
00126 XmlRpc::XmlRpcValue name = xpr["name"];
00127
00128 std::string tmp = static_cast<std::string>(name);
00129
00130 pr.name = tmp;
00131
00132 }
00133
00134
00135 if (!xpr.hasMember("position")) {
00136
00137 ROS_ERROR("Preset doesn't have 'position' property defined.");
00138 continue;
00139
00140 } else {
00141
00142 XmlRpc::XmlRpcValue pos = xpr["position"];
00143
00144 if (pos.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00145
00146 if (pos.size() != 3) {
00147
00148 ROS_ERROR("Strange number of positions (%d)",pos.size());
00149 continue;
00150
00151 }
00152
00153
00154 XmlRpc::XmlRpcValue p = pos[0];
00155 double tmp = static_cast<double>(p);
00156 pr.pose.position.x = tmp;
00157
00158 p = pos[1];
00159 tmp = static_cast<double>(p);
00160 pr.pose.position.y = tmp;
00161
00162 p = pos[2];
00163 tmp = static_cast<double>(p);
00164 pr.pose.position.z = tmp;
00165
00166 } else {
00167
00168 ROS_ERROR("Property 'forces' is defined in bad way.");
00169 continue;
00170
00171 }
00172
00173 }
00174
00175
00176
00177 if (!xpr.hasMember("orientation")) {
00178
00179 ROS_ERROR("Preset doesn't have 'orientation' property defined.");
00180 continue;
00181
00182 } else {
00183
00184 XmlRpc::XmlRpcValue ori = xpr["orientation"];
00185
00186 if (ori.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00187
00188
00189 if (ori.size() == 3) {
00190
00191 geometry_msgs::Vector3 rpy;
00192
00193 XmlRpc::XmlRpcValue p = ori[0];
00194 double tmp = static_cast<double>(p);
00195
00196 rpy.x = tmp;
00197
00198 p = ori[1];
00199 tmp = static_cast<double>(p);
00200 rpy.y = tmp;
00201
00202 p = ori[2];
00203 tmp = static_cast<double>(p);
00204 rpy.z = tmp;
00205
00206 pr.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(rpy.x,rpy.y,rpy.z);
00207
00208
00209 } else if (ori.size() == 4) {
00210
00211
00212
00213 XmlRpc::XmlRpcValue p = ori[0];
00214 double tmp = static_cast<double>(p);
00215 pr.pose.orientation.x = tmp;
00216
00217 p = ori[1];
00218 tmp = static_cast<double>(p);
00219 pr.pose.orientation.y = tmp;
00220
00221 p = ori[2];
00222 tmp = static_cast<double>(p);
00223 pr.pose.orientation.z = tmp;
00224
00225 p = ori[3];
00226 tmp = static_cast<double>(p);
00227 pr.pose.orientation.w = tmp;
00228
00229 } else {
00230
00231 ROS_ERROR("Prop 'orientation' should have 3 or 4 values (%d).",ori.size());
00232 continue;
00233
00234 }
00235
00236
00237
00238
00239
00240 } else {
00241
00242 ROS_ERROR("Property 'target_pos' is defined in bad way.");
00243 continue;
00244
00245 }
00246
00247 }
00248
00249
00250 if (!xpr.hasMember("relative")) {
00251
00252 ROS_ERROR("Preset doesn't have 'relative' property defined.");
00253 continue;
00254
00255 } else {
00256
00257 XmlRpc::XmlRpcValue rel = xpr["relative"];
00258
00259 bool tmp = static_cast<bool>(rel);
00260
00261 pr.relative = tmp;
00262
00263 }
00264
00265
00266 presets_.push_back(pr);
00267
00268 }
00269
00270 } else {
00271
00272 ROS_ERROR("Can't get presets for predefined IM positions.");
00273
00274 }
00275
00276 wxArrayString prt;
00277
00278 prt.Add(wxString::FromAscii("none"));
00279
00280 for(unsigned int i=0; i < presets_.size(); i++) {
00281
00282 std::string tmp;
00283
00284 tmp = presets_[i].name;
00285
00286 if (presets_[i].relative) tmp += " (R)";
00287 else tmp += " (A)";
00288
00289 prt.Add(wxString::FromAscii(tmp.c_str()));
00290
00291 }
00292
00293 presets_choice_ = new wxChoice(this, ID_CHOICE,wxDefaultPosition,wxDefaultSize,prt);
00294
00295 buttons_["stop"] = new wxButton(this, ID_BUTTON_STOP_TRAJ, wxT("Stop"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00296
00297 buttons_["success"] = new wxButton(this, ID_BUTTON_SUCCESS, wxT("Task completed"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00298 buttons_["failed"] = new wxButton(this, ID_BUTTON_FAILED, wxT("Cannot complete task"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00299 buttons_["repeat"] = new wxButton(this, ID_BUTTON_REPEAT, wxT("Repeat detection"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00300
00301
00302
00303 buttons_["undo"] = new wxButton(this, ID_BUTTON_UNDO, wxT("Undo marker movement"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00304
00305
00306
00307
00308
00309
00310
00311 buttons_["new"] = new wxButton(this, ID_BUTTON_NEW, wxT("Start arm planning"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00312 buttons_["plan"] = new wxButton(this, ID_BUTTON_PLAN, wxT("Simulate movement"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00313 buttons_["execute"] = new wxButton(this, ID_BUTTON_EXECUTE, wxT("Execute"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00314
00315
00316
00317
00318
00319
00320
00321 buttons_["stop"]->SetForegroundColour (wxColour (255, 255, 255));
00322 buttons_["stop"]->SetBackgroundColour (wxColour (255, 108, 108));
00323
00324 m_pos_lock_ = new wxCheckBox(this,ID_CHECKBOX_POS,wxT("position"),wxDefaultPosition,wxDefaultSize);
00325 m_or_lock_ = new wxCheckBox(this,ID_CHECKBOX_OR,wxT("orientation"),wxDefaultPosition,wxDefaultSize);
00326
00327 m_aco_ = new wxCheckBox(this,ID_CHECKBOX_ACO,wxT("Avoid fingers collisions"),wxDefaultPosition,wxDefaultSize);
00328
00329
00330 m_aco_->Enable(false);
00331 m_aco_->Set3StateValue(wxCHK_UNDETERMINED);
00332
00333 m_pos_lock_->Enable(false);
00334 m_or_lock_->Enable(false);
00335
00336 m_pos_lock_->Set3StateValue(wxCHK_UNDETERMINED);
00337 m_or_lock_->Set3StateValue(wxCHK_UNDETERMINED);
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 m_text_status = new wxStaticText(this, -1, wxT("status: not initialized yet."));
00363
00364 m_text_predef_pos_ = new wxStaticText(this, -1, wxT("Move to predefined position"));
00365
00366
00367 m_text_action_ = new wxStaticText(this, -1, wxT("Current task:"));
00368 m_text_task_ = new wxTextCtrl(this,-1,wxT("None."),wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE|wxTE_READONLY);
00369 m_text_task_->SetSizeHints(200,100);
00370
00371
00372
00373
00374 disableControls();
00375
00376 wxSizer *vsizer = new wxBoxSizer(wxVERTICAL);
00377
00378 wxSizer *vsizer_top = new wxStaticBoxSizer(wxVERTICAL,this,wxT("Trajectory planning"));
00379
00380 wxSizer *vsizer_mes = new wxStaticBoxSizer(wxVERTICAL,this,wxT("Task"));
00381
00382
00383 wxSizer *vsizer_sn = new wxStaticBoxSizer(wxVERTICAL,this,wxT("SpaceNavigator locks"));
00384 wxSizer *hsizer_sn_in = new wxBoxSizer(wxHORIZONTAL);
00385
00386 hsizer_sn_in->Add(m_pos_lock_,ID_CHECKBOX_POS);
00387 hsizer_sn_in->Add(m_or_lock_,ID_CHECKBOX_OR);
00388
00389 vsizer_sn->Add(hsizer_sn_in,1,wxEXPAND);
00390
00391
00392
00393 wxSizer *vsizer_add = new wxStaticBoxSizer(wxVERTICAL,this,wxT("Additional controls"));
00394
00395
00396
00397 vsizer_top->Add(buttons_["new"]);
00398 vsizer_top->Add(buttons_["plan"]);
00399 vsizer_top->Add(buttons_["execute"]);
00400 vsizer_top->Add(buttons_["stop"]);
00401 vsizer_top->Add(m_text_status);
00402
00403
00404
00405
00406
00407 vsizer_mes->Add(buttons_["success"]);
00408 vsizer_mes->Add(buttons_["repeat"]);
00409 vsizer_mes->Add(buttons_["failed"]);
00410 vsizer_mes->Add(m_text_action_);
00411 vsizer_mes->Add(m_text_task_);
00412
00413
00414 vsizer_add->Add(m_aco_);
00415 vsizer_add->Add(buttons_["undo"]);
00416
00417
00418 vsizer_add->Add(m_text_predef_pos_);
00419 vsizer_add->Add(presets_choice_);
00420
00421
00422 vsizer->Add(vsizer_top,0,wxEXPAND|wxHORIZONTAL);
00423 vsizer->Add(vsizer_mes,0,wxEXPAND|wxHORIZONTAL);
00424 vsizer->Add(vsizer_add,0,wxEXPAND|wxHORIZONTAL);
00425 vsizer->Add(vsizer_sn,0,wxEXPAND|wxHORIZONTAL);
00426
00427 allow_repeat_ = false;
00428
00429
00430 aco_ = false;
00431
00432
00433
00434
00435 spacenav_pos_lock_ = false;
00436 spacenav_or_lock_ = false;
00437
00438
00439
00440
00441
00442 vsizer->SetSizeHints(this);
00443 this->SetSizerAndFit(vsizer);
00444
00445
00446
00447 arm_nav_state_sub_ = nh.subscribe("/but_arm_manip/state",10, &CArmManipulationControls::stateCallback,this);
00448
00449 initialized_ = false;
00450 state_received_ = false;
00451 stop_gui_thread_ = false;
00452 planning_started_ = false;
00453 trajectory_planned_ = false;
00454 arm_nav_called_ = false;
00455
00456 t_gui_update = boost::thread(&CArmManipulationControls::GuiUpdateThread,this);
00457
00461 service_start_ = nh.advertiseService(SRV_START,&CArmManipulationControls::nav_start,this);
00462
00463
00464
00465
00466
00467
00468
00469 }
00471
00472
00473 void CArmManipulationControls::setControlsToDefaultState() {
00474
00475 planning_started_ = false;
00476
00477 buttons_["new"]->SetLabel(wxT("Start arm planning"));
00478
00479 if (wait_for_start_) setButton("new",false);
00480 else setButton("new",true);
00481
00482 if (arm_nav_called_) {
00483
00484 setButton("new",true);
00485
00486 if (allow_repeat_) setButton("repeat",true);
00487 else setButton("repeat",false);
00488
00489 if (traj_executed_ > 0) {
00490
00491 setButton("success",true);
00492 }
00493
00494 } else {
00495
00496 setButton("success",false);
00497 setButton("failed",false);
00498 setButton("repeat",false);
00499
00500 }
00501
00502 setButton("plan",false);
00503 setButton("execute",false);
00504 m_aco_->Enable(true);
00505 setButton("stop",false);
00506 setButton("undo",false);
00507 presets_choice_->Enable(false);
00508 presets_choice_->Select(0);
00509
00510 }
00511
00512 void CArmManipulationControls::disableControls() {
00513
00514 setButton("new",false);
00515
00516 setButton("plan",false);
00517 setButton("execute",false);
00518
00519 m_aco_->Enable(false);
00520
00521 setButton("success",false);
00522 setButton("failed",false);
00523 setButton("repeat",false);
00524
00525 setButton("undo",false);
00526
00527 setButton("stop",false);
00528
00529
00530 presets_choice_->Enable(false);
00531
00532 }
00533
00534
00535 void CArmManipulationControls::stateCallback(const AssistedArmNavigationState::ConstPtr& msg) {
00536
00537 ROS_INFO_ONCE("State received.");
00538
00539 if (!state_received_) {
00540
00541 state_received_ = true;
00542
00543 aco_ = msg->aco_state;
00544
00545 }
00546
00547 if ( (spacenav_pos_lock_ != msg->position_locked) || (spacenav_or_lock_ != msg->orientation_locked) ) {
00548
00549 spacenav_pos_lock_ = msg->position_locked;
00550 spacenav_or_lock_ = msg->orientation_locked;
00551
00552 }
00553
00554 }
00555
00556 void CArmManipulationControls::GuiUpdateThread() {
00557
00558 ROS_INFO("Assisted arm nav. GUI thread started.");
00559
00560 ros::Rate r(5);
00561
00562 while(!stop_gui_thread_ && ros::ok()) {
00563
00564 if ( (!initialized_) && state_received_) {
00565
00566 wxMutexGuiEnter();
00567
00568 if (aco_) m_aco_->Set3StateValue(wxCHK_CHECKED);
00569 else m_aco_->Set3StateValue(wxCHK_UNCHECKED);
00570
00571 setControlsToDefaultState();
00572
00573
00574
00575 if (wait_for_start_) m_text_status->SetLabel(wxT("status: waiting for task"));
00576 else m_text_status->SetLabel(wxT("status: let's start"));
00577
00578 wxMutexGuiLeave();
00579
00580 ROS_INFO("Assisted arm nav. plugin initialized.");
00581
00582 initialized_ = true;
00583
00584 }
00585
00586 if (planning_started_) {
00587
00588
00589 wxMutexGuiEnter();
00590
00591 if (spacenav_pos_lock_) m_pos_lock_->Set3StateValue(wxCHK_CHECKED);
00592 else m_pos_lock_->Set3StateValue(wxCHK_UNCHECKED);
00593
00594 if (spacenav_or_lock_) m_or_lock_->Set3StateValue(wxCHK_CHECKED);
00595 else m_or_lock_->Set3StateValue(wxCHK_UNCHECKED);
00596
00597 wxMutexGuiLeave();
00598
00599 }
00600
00601 r.sleep();
00602
00603 }
00604
00605 ROS_INFO("Stopping assisted arm nav. GUI thread.");
00606 stop_gui_thread_ = false;
00607
00608 }
00609
00610
00611 void CArmManipulationControls::setButton(string but, bool state) {
00612
00613 if (buttons_[but]!=NULL)
00614 buttons_[but]->Enable(state);
00615
00616 }
00617
00618
00619
00620 CArmManipulationControls::~CArmManipulationControls() {
00621
00622 stop_gui_thread_ = true;
00623
00624 ROS_INFO("Waiting for threads to finish.");
00625
00626 t_gui_update.join();
00627
00628
00629
00630 ButtonsMap::iterator it;
00631
00632 for (it = buttons_.begin(); it != buttons_.end(); ++it)
00633 delete it->second;
00634
00635 buttons_.clear();
00636
00637 delete m_aco_;
00638 delete m_text_status;
00639
00640
00641
00642
00643 ROS_INFO("Exiting...");
00644
00645 }
00646
00647 void CArmManipulationControls::NewThread() {
00648
00649
00650
00651 if (!refresh()) {
00652
00653 setControlsToDefaultState();
00654
00655 return;
00656
00657 }
00658
00659 ROS_INFO("Request for new trajectory");
00660
00661 ArmNavNew srv;
00662 std::string status = "";
00663 bool success = false;
00664
00665 if (ros::service::call(SRV_NEW,srv) ) {
00666
00667 if (srv.response.completed) {
00668
00669 success = true;
00670
00671 status = "status: Perform requested action.";
00672
00673
00674
00675
00676 } else {
00677
00678 status = "status: " + srv.response.error;
00679
00680 }
00681
00682 } else {
00683
00684 ROS_ERROR("Failed when calling arm_nav_new service");
00685 status = "status: Communication error.";
00686
00687 }
00688
00689 wxMutexGuiEnter();
00690
00691 m_text_status->SetLabel(wxString::FromAscii(status.c_str()));
00692
00693 if (success) {
00694
00695 disableControls();
00696
00697 buttons_["new"]->SetLabel(wxT("Cancel planning"));
00698 planning_started_ = true;
00699
00700 setButton("new",true);
00701 setButton("plan",true);
00702 setButton("undo",true);
00703
00704
00705 presets_choice_->Enable(true);
00706
00707
00708 if (arm_nav_called_) {
00709
00710 if (allow_repeat_) buttons_["repeat"]->Enable(true);
00711 buttons_["failed"]->Enable(true);
00712
00713 }
00714
00715
00716 } else {
00717
00718
00719 setControlsToDefaultState();
00720
00721 }
00722
00723 wxMutexGuiLeave();
00724
00725 }
00726
00727
00728 bool CArmManipulationControls::refresh() {
00729
00730 ROS_INFO("Refreshing planning scene");
00731
00732 ArmNavRefresh srv;
00733
00734 if ( ros::service::exists(SRV_REFRESH,true) && ros::service::call(SRV_REFRESH,srv) ) {
00735
00736 if (srv.response.completed) {
00737
00738 wxMutexGuiEnter();
00739 m_text_status->SetLabel(wxString::FromAscii("status: Refreshed. Please wait."));
00740 wxMutexGuiLeave();
00741
00742 } else {
00743
00744 wxMutexGuiEnter();
00745 m_text_status->SetLabel(wxString::FromAscii("status: Error on refreshing."));
00746 wxMutexGuiLeave();
00747 return false;
00748
00749 }
00750
00751 } else {
00752
00753 ROS_ERROR("failed when calling arm_nav_refresh service");
00754 wxMutexGuiEnter();
00755 m_text_status->SetLabel(wxString::FromAscii("status: Communication error"));
00756 wxMutexGuiLeave();
00757 return false;
00758
00759 }
00760
00761 return true;
00762
00763 }
00764
00765
00766 void CArmManipulationControls::OnNew(wxCommandEvent& event) {
00767
00768 trajectory_planned_ = false;
00769
00770 if (!planning_started_) {
00771
00772
00773
00774 if (!ros::service::exists(SRV_NEW,true)) {
00775
00776 m_text_status->SetLabel(wxString::FromAscii("status: communication error"));
00777 ROS_ERROR("Service %s is not ready.",((std::string)SRV_NEW).c_str());
00778 return;
00779
00780 }
00781
00782 boost::posix_time::time_duration td = boost::posix_time::milliseconds(100);
00783
00785 if (t_new.timed_join(td)) {
00786
00787 disableControls();
00788
00789 m_text_status->SetLabel(wxString::FromAscii("status: Please wait..."));
00790
00791 t_new = boost::thread(&CArmManipulationControls::NewThread,this);
00792
00793 } else ROS_INFO("We have to wait until new thread finishes.");
00794
00795 } else {
00796
00797
00798 ROS_INFO("Reset planning stuff to initial state");
00799
00800 ArmNavReset srv;
00801
00802 if ( ros::service::exists(SRV_RESET,true) && ros::service::call(SRV_RESET,srv) ) {
00803
00804 if (srv.response.completed) {
00805
00806 m_text_status->SetLabel(wxString::FromAscii("status: Ok, try it again"));
00807
00808 } else {
00809
00810 m_text_status->SetLabel(wxString::FromAscii(srv.response.error.c_str()));
00811
00812 }
00813
00814 } else {
00815
00816 ROS_ERROR("failed when calling arm_nav_reset service");
00817 m_text_status->SetLabel(wxString::FromAscii("status: Communication error"));
00818
00819 }
00820
00821 setControlsToDefaultState();
00822
00823 buttons_["new"]->SetLabel(wxT("Start arm planning"));
00824 planning_started_ = false;
00825
00826 }
00827
00828 }
00829
00830
00831 void CArmManipulationControls::PlanThread() {
00832
00833 ROS_INFO("Starting planning and filtering of new trajectory");
00834
00835 std::string status = "";
00836 bool success = false;
00837
00838 ArmNavPlan srv;
00839
00840 if (ros::service::call(SRV_PLAN,srv) ) {
00841
00842 success = true;
00843
00844 if (srv.response.completed) {
00845
00846 status = "status: Trajectory is ready";
00847 trajectory_planned_ = true;
00848
00849 }
00850 else status = "status: " + srv.response.error;
00851
00852 } else {
00853
00854 success = false;
00855 ROS_ERROR("failed when calling service");
00856 status = "status: Communication error";
00857
00858 }
00859
00860 wxMutexGuiEnter();
00861
00862 m_text_status->SetLabel(wxString::FromAscii(status.c_str()));
00863
00864 if (success) {
00865
00866 disableControls();
00867
00868 setButton("new",true);
00869 setButton("execute",true);
00870 setButton("plan",true);
00871
00872 if (arm_nav_called_) {
00873
00874 if (allow_repeat_) buttons_["repeat"]->Enable(true);
00875 buttons_["failed"]->Enable(true);
00876
00877 }
00878
00879 } else {
00880
00881 disableControls();
00882 setButton("new",true);
00883 setButton("plan",true);
00884
00885 if (arm_nav_called_) {
00886
00887 if (allow_repeat_) buttons_["repeat"]->Enable(true);
00888 buttons_["failed"]->Enable(true);
00889
00890 }
00891
00892 }
00893
00894 wxMutexGuiLeave();
00895
00896 }
00897
00898 void CArmManipulationControls::OnPlan(wxCommandEvent& event)
00899 {
00900
00901 if (!trajectory_planned_) {
00902
00903 if (!ros::service::exists(SRV_PLAN,true)) {
00904
00905 m_text_status->SetLabel(wxString::FromAscii("status: communication error"));
00906 ROS_ERROR("Service %s is not ready.",((std::string)SRV_NEW).c_str());
00907 return;
00908
00909 }
00910
00911 boost::posix_time::time_duration td = boost::posix_time::milliseconds(100);
00912
00914 if (t_plan.timed_join(td)) {
00915
00916 m_text_status->SetLabel(wxString::FromAscii("status: Planning. Please wait..."));
00917
00918 disableControls();
00919
00920 t_plan = boost::thread(&CArmManipulationControls::PlanThread,this);
00921
00922 } else ROS_INFO("We have to wait until PLAN thread finishes.");
00923
00924 } else {
00925
00926 ArmNavPlay srv;
00927
00928 if ( ros::service::exists(SRV_PLAY,true) && ros::service::call(SRV_PLAY,srv) ) {
00929
00930 if (srv.response.completed) {
00931
00932 m_text_status->SetLabel(wxString::FromAscii("status: Playing trajectory..."));
00933
00934 } else {
00935
00936 m_text_status->SetLabel(wxString::FromAscii(srv.response.error.c_str()));
00937
00938 }
00939
00940 } else {
00941
00942 ROS_ERROR("failed when calling arm_nav_play service");
00943 m_text_status->SetLabel(wxString::FromAscii("status: Communication error"));
00944
00945 }
00946
00947 }
00948
00949 }
00950
00951
00952
00953 void CArmManipulationControls::OnSwitch(wxCommandEvent& event)
00954 {
00955
00956 if (aco_) ROS_INFO("Lets switch attached collision object OFF");
00957 else ROS_INFO("Lets switch attached collision object ON");
00958
00959 ArmNavSwitchAttCO srv;
00960
00961 srv.request.state = !aco_;
00962
00963 if ( ros::service::exists(SRV_SWITCH,true) && ros::service::call(SRV_SWITCH,srv) ) {
00964
00965 if (srv.response.completed) {
00966
00967
00968
00969 aco_ = !aco_;
00970
00971
00972
00973
00974 } else {
00975
00976 m_text_status->SetLabel(wxString::FromAscii("Can't switch state of ACO"));
00977
00978 if (aco_) m_aco_->Set3StateValue(wxCHK_CHECKED);
00979 else m_aco_->Set3StateValue(wxCHK_UNCHECKED);
00980
00981 }
00982
00983 } else {
00984
00985 std::string tmp = SRV_SWITCH;
00986
00987 ROS_ERROR("failed when calling %s service",tmp.c_str());
00988 m_text_status->SetLabel(wxString::FromAscii("status: Communication error"));
00989
00990 if (aco_) m_aco_->Set3StateValue(wxCHK_CHECKED);
00991 else m_aco_->Set3StateValue(wxCHK_UNCHECKED);
00992
00993 }
00994
00995
00996 }
00997
00998
00999 void CArmManipulationControls::OnExecute(wxCommandEvent& event) {
01000
01001 if (!ros::service::exists(SRV_EXECUTE,true)) {
01002
01003 m_text_status->SetLabel(wxString::FromAscii("status: communication error"));
01004 ROS_ERROR("Service %s is not ready.",((std::string)SRV_NEW).c_str());
01005 return;
01006
01007 }
01008
01009 boost::posix_time::time_duration td = boost::posix_time::milliseconds(100);
01010
01012 if (t_execute.timed_join(td)) {
01013
01014 disableControls();
01015 setButton("stop",true);
01016 m_text_status->SetLabel(wxT("status: Executing trajectory..."));
01017
01018 t_execute = boost::thread(&CArmManipulationControls::ExecuteThread,this);
01019
01020 } else ROS_INFO("We have to wait until EXECUTE thread finishes.");
01021
01022 }
01023
01024 void CArmManipulationControls::ExecuteThread()
01025 {
01026 ROS_INFO("Execution of planned trajectory has been started");
01027
01028 ArmNavExecute srv;
01029
01030 std::string status = "";
01031 bool success = false;
01032
01033 if (ros::service::call(SRV_EXECUTE,srv) ) {
01034
01035 if (srv.response.completed) {
01036
01037 success = true;
01038 status = "status: Trajectory was executed.";
01039 traj_executed_++;
01040
01041 } else {
01042
01043 success = false;
01044 status = srv.response.error;
01045
01046 }
01047
01048 } else {
01049
01050 ROS_ERROR("failed when calling arm_nav_execute service");
01051 success = false;
01052 status = "status: Communication error";
01053
01054 }
01055
01056 wxMutexGuiEnter();
01057
01058 m_text_status->SetLabel(wxString::FromAscii(status.c_str()));
01059
01060
01061
01062 setControlsToDefaultState();
01063
01064
01065 if (arm_nav_called_) {
01066
01067 if (allow_repeat_) setButton("repeat",true);
01068 setButton("failed",true);
01069 setButton("success",true);
01070
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080 buttons_["new"]->SetLabel(wxT("Start arm planning"));
01081 m_pos_lock_->Set3StateValue(wxCHK_UNDETERMINED);
01082 m_or_lock_->Set3StateValue(wxCHK_UNDETERMINED);
01083
01084 wxMutexGuiLeave();
01085
01086 }
01087
01088
01089 void CArmManipulationControls::OnSuccess(wxCommandEvent& event)
01090 {
01091 ROS_INFO("Finishing manual arm manipulation task");
01092
01093 ArmNavSuccess srv;
01094
01095 if ( ros::service::exists(SRV_SUCCESS,true) && ros::service::call(SRV_SUCCESS,srv) ) {
01096
01097 m_text_status->SetLabel(wxString::FromAscii("status: Succeeded :-)"));
01098
01099 } else {
01100
01101 ROS_ERROR("failed when calling arm_nav_success service");
01102 m_text_status->SetLabel(wxString::FromAscii("Communication error"));
01103
01104 }
01105
01106
01107
01108
01109 setTask("None.");
01110
01111
01112 arm_nav_called_ = false;
01113 setControlsToDefaultState();
01114
01115 }
01116
01117 void CArmManipulationControls::setTask(std::string text) {
01118
01119 m_text_task_->Clear();
01120 m_text_task_->AppendText(wxString::FromAscii(text.c_str()));
01121
01122 }
01123
01124 void CArmManipulationControls::OnFailed(wxCommandEvent& event)
01125 {
01126 ROS_ERROR("Manual arm manipulation task failed");
01127
01128 ArmNavFailed srv;
01129
01130 if ( ros::service::exists(SRV_FAILED,true) && ros::service::call(SRV_FAILED,srv) ) {
01131
01132 m_text_status->SetLabel(wxString::FromAscii("status: Failed :-("));
01133
01134
01135 setTask("None.");
01136
01137 } else {
01138
01139 ROS_ERROR("failed when calling arm_nav_failed service");
01140 m_text_status->SetLabel(wxString::FromAscii("Communication error"));
01141
01142
01143 }
01144
01145 arm_nav_called_ = false;
01146 setControlsToDefaultState();
01147
01148 }
01149
01150 void CArmManipulationControls::OnRepeat(wxCommandEvent& event)
01151 {
01152 ROS_ERROR("Request for repeat of manual arm navigation task");
01153
01154 ArmNavRepeat srv;
01155
01156 if ( ros::service::exists(SRV_REPEAT,true) && ros::service::call(SRV_REPEAT,srv) ) {
01157
01158 m_text_status->SetLabel(wxString::FromAscii("status: Repeating action..."));
01159
01160
01161 setTask("None.");
01162
01163 } else {
01164
01165 ROS_ERROR("failed when calling arm_nav_repeat service");
01166 m_text_status->SetLabel(wxString::FromAscii("Communication error"));
01167
01168 }
01169
01170 arm_nav_called_ = false;
01171 setControlsToDefaultState();
01172
01173 }
01174
01175
01176 bool CArmManipulationControls::nav_start(ArmNavStart::Request &req, ArmNavStart::Response &res) {
01177
01178 char str[120];
01179
01180 action_ = req.action;
01181 object_name_ = req.object_name;
01182 allow_repeat_ = req.allow_repeat;
01183 traj_executed_ = 0;
01184
01185 if (allow_repeat_) ROS_INFO("Received request for action. Repeated detection is allowed.");
01186 else ROS_INFO("Received request for action. Repeated detection is NOT allowed.");
01187
01188
01189 if (req.object_name!="") {
01190
01191 snprintf(str,120,"%s (%s)",req.action.c_str(),req.object_name.c_str());
01192
01193 std::string tmp;
01194 tmp = std::string("object_name: ") + object_name_;
01195
01196
01197 } else {
01198
01199 snprintf(str,120,"%s",req.action.c_str());
01200
01201 std::string tmp;
01202 tmp = std::string("object_name: none");
01203
01204
01205 }
01206
01207 std::string tmp;
01208 tmp = std::string("action: ") + req.action;
01209
01210 setTask(req.action);
01211
01212
01213 wxMessageBox(wxString::FromAscii(str), wxString::FromAscii("Assisted arm navigation"), wxOK, parent_,-1,-1);
01214
01215 setButton("new",true);
01216 arm_nav_called_ = true;
01217
01218
01219 res.completed = true;
01220
01221 return true;
01222
01223 };
01224
01225
01226 void CArmManipulationControls::OnStepBack(wxCommandEvent& event) {
01227
01228 ROS_INFO("Undoing last change in IM pose");
01229
01230 setButton("undo",false);
01231
01232 ArmNavStep srv;
01233
01234 srv.request.undo = true;
01235
01236 if ( ros::service::exists(SRV_STEP,true) && ros::service::call(SRV_STEP,srv) ) {
01237
01238 if (srv.response.completed) {
01239
01240 m_text_status->SetLabel(wxString::FromAscii("status: Undo was successful."));
01241
01242 } else {
01243
01244 m_text_status->SetLabel(wxString::FromAscii("status: Error on undoing."));
01245
01246 }
01247
01248 } else {
01249
01250 ROS_ERROR("failed when calling arm_nav_step service");
01251 m_text_status->SetLabel(wxString::FromAscii("status: Communication error"));
01252
01253 }
01254
01255 setButton("undo",true);
01256
01257 }
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314 void CArmManipulationControls::OnStopTraj(wxCommandEvent& event) {
01315
01316 ROS_INFO("Stopping execution of trajectory");
01317
01318 ArmNavStop srv;
01319
01320 if ( ros::service::exists(SRV_STOP,true) && ros::service::call(SRV_STOP,srv) ) {
01321
01322 m_text_status->SetLabel(wxString::FromAscii("status: Execution canceled."));
01323
01324 } else {
01325
01326 ROS_ERROR("failed when calling arm_nav_stop service");
01327 m_text_status->SetLabel(wxString::FromAscii("status: Communication error"));
01328
01329 }
01330
01331 m_pos_lock_->Set3StateValue(wxCHK_UNDETERMINED);
01332 m_or_lock_->Set3StateValue(wxCHK_UNDETERMINED);
01333
01334
01335
01336 setControlsToDefaultState();
01337
01338 if (arm_nav_called_) {
01339
01340 if (allow_repeat_) buttons_["repeat"]->Enable(true);
01341 buttons_["failed"]->Enable(true);
01342
01343 }
01344
01345 }
01346
01347
01348 bool CArmManipulationControls::checkService(std::string srv) {
01349
01350 if (!ros::service::exists(srv,true)) {
01351
01352 ROS_ERROR("Service %s is not ready.",srv.c_str());
01353 m_text_status->SetLabel(wxString::FromAscii("status: communication error"));
01354 setControlsToDefaultState();
01355 return false;
01356
01357 } else return true;
01358
01359 }
01360
01361 void CArmManipulationControls::OnChoice(wxCommandEvent& event) {
01362
01363 unsigned int choice;
01364 if (presets_choice_->GetSelection() > 0) choice = (presets_choice_->GetSelection()) - 1;
01365 else return;
01366
01367 if (presets_[choice].relative) {
01368
01369 if (!checkService(SRV_MOVE_PALM_LINK_REL)) return;
01370
01371 boost::posix_time::time_duration td = boost::posix_time::milliseconds(100);
01372
01374 if (t_move_rel.timed_join(td)) {
01375
01376 disableControls();
01377 m_text_status->SetLabel(wxT("status: Moving to predefined position."));
01378
01379 t_move_rel = boost::thread(&CArmManipulationControls::MoveRel,this);
01380
01381 } else ROS_DEBUG("We have to wait until MOVE_REL thread finishes.");
01382
01383
01384
01385 } else {
01386
01387
01388 if (!checkService(SRV_MOVE_PALM_LINK)) return;
01389
01390 boost::posix_time::time_duration td = boost::posix_time::milliseconds(100);
01391
01393 if (t_move_abs.timed_join(td)) {
01394
01395 disableControls();
01396 m_text_status->SetLabel(wxT("status: Moving to predefined position."));
01397
01398 t_move_abs = boost::thread(&CArmManipulationControls::MoveAbs,this);
01399
01400 } else ROS_DEBUG("We have to wait until MOVE_ABS thread finishes.");
01401
01402
01403
01404 }
01405
01406
01407 }
01408
01409 void CArmManipulationControls::MoveAbs() {
01410
01411
01412 unsigned int choice;
01413 wxMutexGuiEnter();
01414 if (presets_choice_->GetSelection() > 0) choice = (presets_choice_->GetSelection()) - 1;
01415 else {
01416
01417 wxMutexGuiLeave();
01418 return;
01419 }
01420 wxMutexGuiLeave();
01421
01422 geometry_msgs::PoseStamped npose;
01423
01424 npose.header.stamp = ros::Time::now();
01425 npose.header.frame_id = "/base_link";
01426
01427 npose.pose = presets_[choice].pose;
01428
01429 ArmNavMovePalmLink srv;
01430
01431 srv.request.sdh_palm_link_pose = npose;
01432
01433 bool ret = false;;
01434
01435 if ( ros::service::call(SRV_MOVE_PALM_LINK,srv) ) {
01436
01437 if (!srv.response.completed) ret = false;
01438 else ret = true;
01439
01440 } else {
01441
01442 ROS_ERROR("failed when called %s service",SRV_MOVE_PALM_LINK.c_str());
01443 ret = false;
01444
01445 }
01446
01447
01448 if (!ret) {
01449
01450 wxMutexGuiEnter();
01451 m_text_status->SetLabel(wxString::FromAscii("status: Error on moving IM to new position."));
01452 setControlsToDefaultState();
01453 wxMutexGuiLeave();
01454 return;
01455
01456 } else {
01457
01458 wxMutexGuiEnter();
01459 m_text_status->SetLabel(wxString::FromAscii("status: Gripper is at new position."));
01460
01461 setButton("new",true);
01462 setButton("plan",true);
01463 setButton("undo",true);
01464
01465 presets_choice_->Enable(true);
01466 presets_choice_->Select(0);
01467
01468 if (arm_nav_called_) {
01469
01470 if (allow_repeat_) buttons_["repeat"]->Enable(true);
01471 buttons_["failed"]->Enable(true);
01472
01473 }
01474
01475 wxMutexGuiLeave();
01476 return;
01477
01478
01479 }
01480
01481 }
01482
01483 void CArmManipulationControls::MoveRel() {
01484
01485 unsigned int choice;
01486 wxMutexGuiEnter();
01487 if (presets_choice_->GetSelection() > 0) choice = (presets_choice_->GetSelection()) - 1;
01488 else {
01489
01490 wxMutexGuiLeave();
01491 return;
01492 }
01493 wxMutexGuiLeave();
01494
01495 geometry_msgs::Pose move;
01496 move = presets_[choice].pose;
01497
01498 ArmNavMovePalmLinkRel srv;
01499
01500 srv.request.relative_movement = move;
01501
01502 bool ret = false;
01503 bool err = false;
01504
01505 if ( ros::service::call(SRV_MOVE_PALM_LINK_REL,srv) ) {
01506
01507 if (srv.response.completed) ret = true;
01508 else ret = false;
01509
01510 } else {
01511
01512 ROS_ERROR("failed when called %s service",SRV_MOVE_PALM_LINK_REL.c_str());
01513 err = true;
01514
01515 }
01516
01517
01518 if (!ret || err) {
01519
01520 wxMutexGuiEnter();
01521
01522 if (err) {
01523
01524 m_text_status->SetLabel(wxString::FromAscii("status: Comunnication error."));
01525 setControlsToDefaultState();
01526
01527 }
01528
01529 if (!ret) {
01530
01531 m_text_status->SetLabel(wxString::FromAscii("status: Error on moving IM to new position."));
01532
01533 setButton("new",true);
01534 setButton("plan",true);
01535 setButton("undo",true);
01536
01537 presets_choice_->Enable(true);
01538 presets_choice_->Select(0);
01539
01540 if (arm_nav_called_) {
01541
01542 if (allow_repeat_) buttons_["repeat"]->Enable(true);
01543 buttons_["failed"]->Enable(true);
01544
01545 }
01546
01547 }
01548
01549 wxMutexGuiLeave();
01550 return;
01551
01552 } else {
01553
01554 wxMutexGuiEnter();
01555 m_text_status->SetLabel(wxString::FromAscii("status: Gripper is at new position."));
01556
01557 setButton("new",true);
01558 setButton("plan",true);
01559 setButton("undo",true);
01560
01561 presets_choice_->Enable(true);
01562 presets_choice_->Select(0);
01563
01564 if (arm_nav_called_) {
01565
01566 if (allow_repeat_) buttons_["repeat"]->Enable(true);
01567 buttons_["failed"]->Enable(true);
01568
01569 }
01570
01571 wxMutexGuiLeave();
01572 return;
01573
01574 }
01575
01576
01577 }
01578
01580
01581
01583
01584
01585 BEGIN_EVENT_TABLE(CArmManipulationControls, wxPanel)
01586 EVT_BUTTON(ID_BUTTON_NEW, CArmManipulationControls::OnNew)
01587 EVT_BUTTON(ID_BUTTON_PLAN, CArmManipulationControls::OnPlan)
01588 EVT_BUTTON(ID_BUTTON_EXECUTE, CArmManipulationControls::OnExecute)
01589 EVT_BUTTON(ID_BUTTON_SUCCESS, CArmManipulationControls::OnSuccess)
01590 EVT_BUTTON(ID_BUTTON_FAILED, CArmManipulationControls::OnFailed)
01591
01592 EVT_CHECKBOX(ID_CHECKBOX_ACO,CArmManipulationControls::OnSwitch)
01593 EVT_BUTTON(ID_BUTTON_REPEAT, CArmManipulationControls::OnRepeat)
01594 EVT_BUTTON(ID_BUTTON_UNDO, CArmManipulationControls::OnStepBack)
01595
01596
01597
01598
01599
01600
01601 EVT_BUTTON(ID_BUTTON_STOP_TRAJ, CArmManipulationControls::OnStopTraj)
01602
01603
01604 EVT_CHOICE(ID_CHOICE,CArmManipulationControls::OnChoice)
01605 END_EVENT_TABLE()
01606