$search
00001 /* 00002 * Copyright (c) 2011, Willow Garage, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of the <ORGANIZATION> nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 // Author: Matthew Klingensmith, E. Gil Jones 00031 00032 #include <move_arm_warehouse/planning_scene_warehouse_viewer.h> 00033 #include <qt4/QtGui/qapplication.h> 00034 #include <assert.h> 00035 #include <qt4/QtGui/qsplashscreen.h> 00036 #include <qt4/QtGui/qdialogbuttonbox.h> 00037 #include <qt4/QtGui/qdialog.h> 00038 #include <qt4/QtGui/qheaderview.h> 00039 #include <qt4/QtGui/qimage.h> 00040 #include <ros/package.h> 00041 00042 using namespace collision_space; 00043 using namespace kinematics_msgs; 00044 using namespace arm_navigation_msgs; 00045 using namespace head_monitor_msgs; 00046 using namespace move_arm_warehouse; 00047 using namespace planning_environment; 00048 using namespace planning_models; 00049 using namespace std; 00050 using namespace trajectory_msgs; 00051 using namespace planning_scene_utils; 00052 using namespace ros::param; 00053 WarehouseViewer* psv = NULL; 00054 bool inited = false; 00055 00056 WarehouseViewer::WarehouseViewer(QWidget* parent, planning_scene_utils::PlanningSceneParameters& params) : 00057 QMainWindow(parent), PlanningSceneEditor(params) 00058 { 00059 quit_threads_ = false; 00060 initQtWidgets(); 00061 selected_trajectory_name_ = ""; 00062 warehouse_data_loaded_once_ = false; 00063 table_load_thread_ = NULL; 00064 planning_scene_initialized_ = false; 00065 00066 qRegisterMetaType < std::string > ( "std::string" ); 00067 00068 popupLoadPlanningScenes(); 00069 00070 } 00071 00072 WarehouseViewer::~WarehouseViewer() 00073 { 00074 00075 } 00076 00077 void WarehouseViewer::initQtWidgets() 00078 { 00079 menu_bar_ = new QMenuBar(this); 00080 setMenuBar(menu_bar_); 00081 QWidget* centralWidget = new QWidget(this); 00082 setCentralWidget(centralWidget); 00083 00084 QGroupBox* motionPlanBox = new QGroupBox(this); 00085 motionPlanBox->setTitle("Motion Plan Requests"); 00086 00087 selected_request_label_ = new QLabel(motionPlanBox); 00088 selected_request_label_->setText("Selected Request: None"); 00089 selected_request_label_->setToolTip("Selected motion plan request. New trajectories will be planned for this request."); 00090 00091 QGroupBox* trajectoryBox = new QGroupBox(this); 00092 trajectoryBox->setTitle("Trajectories"); 00093 00094 00095 QVBoxLayout* layout = new QVBoxLayout(this); 00096 layout->addWidget(motionPlanBox); 00097 layout->addWidget(trajectoryBox); 00098 QVBoxLayout* motionBoxLayout = new QVBoxLayout(motionPlanBox); 00099 motion_plan_tree_ = new QTreeWidget(motionPlanBox); 00100 motion_plan_tree_->setColumnCount(5); 00101 motion_plan_tree_->setToolTip("Motion plan tree. Open a motion plan request to access its controls. Click to select a request."); 00102 00103 QVBoxLayout* trajectoryBoxLayout = new QVBoxLayout(trajectoryBox); 00104 file_menu_ = menu_bar_->addMenu("File"); 00105 planning_scene_menu_ = menu_bar_->addMenu("Planning Scene"); 00106 00107 new_planning_scene_action_ = file_menu_->addAction("New Planning Scene ..."); 00108 load_planning_scene_action_ = file_menu_->addAction("Load Planning Scene ..."); 00109 save_planning_scene_action_ = file_menu_->addAction("Save Planning Scene ..."); 00110 copy_planning_scene_action_ = file_menu_->addAction("Save Copy of Planning Scene ..."); 00111 new_motion_plan_action_ = file_menu_->addAction("New Motion Plan Request ..."); 00112 refresh_action_ = planning_scene_menu_->addAction("Refresh Planning Scene..."); 00113 view_outcomes_action_ = planning_scene_menu_->addAction("View Outcomes ..."); 00114 alter_link_padding_action_ = planning_scene_menu_->addAction("Alter Link Padding ..."); 00115 alter_allowed_collision_action_ = planning_scene_menu_->addAction("Alter Allowed Collision Operations ..."); 00116 edit_robot_state_action_ = planning_scene_menu_->addAction("Edit Robot State ..."); 00117 quit_action_ = file_menu_->addAction("Quit"); 00118 00119 collision_object_menu_ = menu_bar_->addMenu("Collision Objects"); 00120 new_object_action_ = collision_object_menu_->addAction("New Primitive Collision Object ..."); 00121 new_mesh_action_ = collision_object_menu_->addAction("New Mesh Collision Object ..."); 00122 00123 planner_configuration_menu_ = menu_bar_->addMenu("Planner configuration"); 00124 set_primary_planner_action_ = planner_configuration_menu_->addAction("Use primary planner"); 00125 set_primary_planner_action_->setCheckable(true); 00126 set_primary_planner_action_->setChecked(true); 00127 set_secondary_planner_action_ = planner_configuration_menu_->addAction("Use secondary planner"); 00128 set_secondary_planner_action_->setCheckable(true); 00129 set_secondary_planner_action_->setChecked(false); 00130 00131 trajectory_tree_ = new QTreeWidget(trajectoryBox); 00132 trajectory_tree_->setColumnCount(8); 00133 00134 00135 QLabel* trajectory_label = new QLabel(trajectoryBox); 00136 trajectory_label->setText("Trajectory Position"); 00137 00138 QGroupBox* buttonsBox = new QGroupBox(trajectoryBox); 00139 QHBoxLayout* buttonLayout = new QHBoxLayout(buttonsBox); 00140 00141 trajectory_slider_ = new QSlider(Qt::Horizontal,trajectoryBox); 00142 trajectory_slider_->setMinimum(0); 00143 trajectory_slider_->setMaximum(0); 00144 00145 QLabel* modeLabel = new QLabel(trajectoryBox); 00146 modeLabel->setText("Selected Trajectory: "); 00147 modeLabel->setToolTip("Selected trajectory."); 00148 00149 play_button_ = new QPushButton(this); 00150 play_button_->setText("Play Trajectory"); 00151 play_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00152 play_button_->setToolTip("Plays the currently selected trajectory in RVIZ. Makes the trajectory visible."); 00153 00154 filter_button_ = new QPushButton(this); 00155 filter_button_->setText("Filter Trajectory"); 00156 filter_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00157 filter_button_->setToolTip("Sends the currently selected trajectory to the trajectory filter, producing a new trajectory."); 00158 00159 if(params_.trajectory_filter_service_name_ == "none") 00160 { 00161 filter_button_->setEnabled(false); 00162 } 00163 00164 replan_button_ = new QPushButton(this); 00165 replan_button_->setText("Plan New Trajectory"); 00166 replan_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00167 replan_button_->setToolTip("Plans a new trajectory between the start and goal states of the current motion plan request, producing a new trajectory."); 00168 00169 if(params_.planner_service_name_ == "none") 00170 { 00171 replan_button_->setEnabled(false); 00172 } 00173 00174 execute_button_ = new QPushButton(this); 00175 execute_button_->setText("Execute On Robot"); 00176 execute_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00177 execute_button_->setEnabled(params_.use_robot_data_); 00178 execute_button_->setToolTip("Sends the currently selected trajectory to the robot's controllers. (Only works if using robot data). Produces a new trajectory."); 00179 00180 trajectory_point_edit_ = new QSpinBox(this); 00181 trajectory_point_edit_->setRange(0, 0); 00182 trajectory_point_edit_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00183 trajectory_point_edit_->setToolTip("Currently displayed trajectory point. Drag to change."); 00184 00185 selected_trajectory_label_ = new QLabel(this); 00186 selected_trajectory_label_->setText("None"); 00187 selected_trajectory_label_->setToolTip("Currently selected trajectory."); 00188 00189 QPushButton* deleteMPRButton = new QPushButton(motionPlanBox); 00190 deleteMPRButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00191 deleteMPRButton->setText("Delete Motion Plan Request"); 00192 deleteMPRButton->setToolTip("Deletes the currently selected motion plan request."); 00193 00194 QPushButton* deleteTrajectoryButton = new QPushButton(trajectoryBox); 00195 deleteTrajectoryButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00196 deleteTrajectoryButton->setText("Delete Trajectory"); 00197 deleteTrajectoryButton->setToolTip("Deletes the currently selected trajectory."); 00198 00199 motionBoxLayout->addWidget(motion_plan_tree_); 00200 motionBoxLayout->addWidget(selected_request_label_); 00201 motionBoxLayout->addWidget(deleteMPRButton); 00202 trajectoryBoxLayout->addWidget(trajectory_tree_); 00203 trajectoryBoxLayout->addWidget(modeLabel); 00204 trajectoryBoxLayout->addWidget(selected_trajectory_label_); 00205 trajectoryBoxLayout->addWidget(trajectory_label); 00206 trajectoryBoxLayout->addWidget(trajectory_point_edit_); 00207 trajectoryBoxLayout->addWidget(trajectory_slider_); 00208 trajectoryBoxLayout->addWidget(deleteTrajectoryButton); 00209 trajectoryBoxLayout->addWidget(buttonsBox); 00210 buttonLayout->addWidget(play_button_); 00211 buttonLayout->addWidget(replan_button_); 00212 buttonLayout->addWidget(filter_button_); 00213 buttonLayout->addWidget(execute_button_); 00214 buttonsBox->setTitle("Trajectory Controls"); 00215 00216 connect(deleteMPRButton, SIGNAL(clicked()), this, SLOT(deleteSelectedMotionPlan())); 00217 connect(deleteTrajectoryButton, SIGNAL(clicked()), this, SLOT(deleteSelectedTrajectory())); 00218 connect(new_planning_scene_action_, SIGNAL(triggered()), this, SLOT(createNewPlanningSceneSlot())); 00219 connect(new_motion_plan_action_, SIGNAL(triggered()), this, SLOT(createNewMotionPlanPressed())); 00220 connect(new_object_action_, SIGNAL(triggered()), this, SLOT(createNewObjectPressed())); 00221 connect(new_mesh_action_, SIGNAL(triggered()), this, SLOT(createNewMeshPressed())); 00222 connect(save_planning_scene_action_, SIGNAL(triggered()), this, SLOT(savePlanningSceneSlot())); 00223 connect(copy_planning_scene_action_, SIGNAL(triggered()), this, SLOT(copyPlanningSceneSlot())); 00224 connect(load_planning_scene_action_, SIGNAL(triggered()), this, SLOT(popupLoadPlanningScenes())); 00225 connect(quit_action_, SIGNAL(triggered()), this, SLOT(quit())); 00226 connect(play_button_, SIGNAL(clicked()), this, SLOT(playButtonPressed())); 00227 connect(filter_button_, SIGNAL(clicked()), this, SLOT(filterButtonPressed())); 00228 connect(trajectory_slider_, SIGNAL(sliderMoved(int)), this, SLOT(sliderDragged(int))); 00229 connect(trajectory_tree_, SIGNAL(itemSelectionChanged()), this, SLOT(trajectoryTableSelection())); 00230 connect(replan_button_, SIGNAL(clicked()), this, SLOT(replanButtonPressed())); 00231 connect(trajectory_point_edit_, SIGNAL(valueChanged(int)), this, SLOT(trajectoryEditChanged())); 00232 connect(motion_plan_tree_, SIGNAL(itemSelectionChanged()), this, SLOT(motionPlanTableSelection())); 00233 connect(this, SIGNAL(updateTables()), this, SLOT(updateStateTriggered())); 00234 connect(execute_button_, SIGNAL(clicked()), this, SLOT(executeButtonPressed())); 00235 connect(refresh_action_, SIGNAL(triggered()), this, SLOT(refreshSceneButtonPressed())); 00236 connect(view_outcomes_action_, SIGNAL(triggered()), this, SLOT(viewOutcomesPressed())); 00237 connect(alter_link_padding_action_, SIGNAL(triggered()), this, SLOT(alterLinkPaddingPressed())); 00238 connect(alter_allowed_collision_action_, SIGNAL(triggered()), this, SLOT(alterAllowedCollisionPressed())); 00239 connect(edit_robot_state_action_, SIGNAL(triggered()), this, SLOT(editRobotStatePressed())); 00240 connect(this, SIGNAL(plannerFailure(int)),this, SLOT(popupPlannerFailure(int))); 00241 connect(this, SIGNAL(filterFailure(int)),this, SLOT(popupFilterFailure(int))); 00242 connect(this, SIGNAL(attachObjectSignal(const std::string&)), this, SLOT(attachObject(const std::string&))); 00243 connect(this, SIGNAL(allScenesLoaded()), this, SLOT(refreshPlanningSceneDialog())); 00244 connect(set_primary_planner_action_, SIGNAL(triggered()), this, SLOT(primaryPlannerTriggered())); 00245 connect(set_secondary_planner_action_, SIGNAL(triggered()), this, SLOT(secondaryPlannerTriggered())); 00246 load_planning_scene_dialog_ = new QDialog(this); 00247 00248 setupPlanningSceneDialog(); 00249 connect(this, SIGNAL(changeProgress(int)), load_scene_progress_, SLOT(setValue(int))); 00250 menu_bar_->setMinimumWidth(500); 00251 buttonsBox->setLayout(buttonLayout); 00252 trajectoryBox->setLayout(trajectoryBoxLayout); 00253 motionPlanBox->setLayout(motionBoxLayout); 00254 centralWidget->setLayout(layout); 00255 00256 createNewObjectDialog(); 00257 createNewMeshDialog(); 00258 createRequestDialog(); 00259 00260 //setCurrentPlanningScene(createNewPlanningScene(), false, false); 00261 00262 } 00263 00264 void WarehouseViewer::createOutcomeDialog() 00265 { 00266 outcome_dialog_ = new QDialog(this); 00267 outcome_dialog_->setWindowTitle("Planning Scene Outcomes"); 00268 QVBoxLayout* layout = new QVBoxLayout(outcome_dialog_); 00269 00270 QGroupBox* stagesBox = new QGroupBox(outcome_dialog_); 00271 stagesBox->setTitle("Planning Stage Outcomes"); 00272 00273 QVBoxLayout* stagesLayout = new QVBoxLayout(stagesBox); 00274 stagesBox->setLayout(stagesLayout); 00275 00276 stage_outcome_table_ = new QTableWidget(stagesBox); 00277 stagesLayout->addWidget(stage_outcome_table_); 00278 00279 QStringList stageHeaders; 00280 stageHeaders.append("Pipeline Stage"); 00281 stageHeaders.append("Outcome"); 00282 00283 stage_outcome_table_->setColumnCount(2); 00284 stage_outcome_table_->setRowCount((int)error_map_.size()); 00285 00286 stage_outcome_table_->setHorizontalHeaderLabels(stageHeaders); 00287 stage_outcome_table_->setColumnWidth(0, 250); 00288 stage_outcome_table_->setColumnWidth(1, 400); 00289 stage_outcome_table_->setMinimumWidth(650); 00290 00291 int r = 0; 00292 for(map<string, ArmNavigationErrorCodes>::iterator it = error_map_.begin(); it != error_map_.end(); it++, r++) 00293 { 00294 QTableWidgetItem* stageItem = new QTableWidgetItem(QString::fromStdString(it->first)); 00295 stageItem->setFlags(Qt::ItemIsEnabled); 00296 stage_outcome_table_->setItem(r,0, stageItem); 00297 00298 QTableWidgetItem* outcomeItem = new QTableWidgetItem(QString::fromStdString(armNavigationErrorCodeToString(it->second))); 00299 outcomeItem->setFlags(Qt::ItemIsEnabled); 00300 stage_outcome_table_->setItem(r,1, outcomeItem); 00301 00302 if(it->second.val != ArmNavigationErrorCodes::SUCCESS) 00303 { 00304 outcomeItem->setTextColor(QColor(150, 0, 0)); 00305 } 00306 00307 } 00308 QGroupBox* trajectoryBox = new QGroupBox(outcome_dialog_); 00309 trajectoryBox->setTitle("Trajectory Outcomes"); 00310 00311 QVBoxLayout* trajectoryLayout = new QVBoxLayout(trajectoryBox); 00312 trajectoryBox->setLayout(trajectoryLayout); 00313 00314 trajectory_outcome_table_ = new QTableWidget(trajectoryBox); 00315 trajectoryLayout->addWidget(trajectory_outcome_table_); 00316 00317 QStringList trajectoryHeaders; 00318 trajectoryHeaders.append("MPR ID"); 00319 trajectoryHeaders.append("Trajectory ID"); 00320 trajectoryHeaders.append("Source"); 00321 trajectoryHeaders.append("Outcome"); 00322 00323 unsigned int count = 0; 00324 for(map<string, map<string, TrajectoryData> >::iterator it = trajectory_map_.begin(); 00325 it != trajectory_map_.end(); 00326 it++) { 00327 count += it->second.size(); 00328 } 00329 00330 trajectory_outcome_table_->setColumnCount(4); 00331 trajectory_outcome_table_->setRowCount(count); 00332 trajectory_outcome_table_->setColumnWidth(0, 150); 00333 trajectory_outcome_table_->setColumnWidth(1, 150); 00334 trajectory_outcome_table_->setColumnWidth(2, 200); 00335 trajectory_outcome_table_->setColumnWidth(3, 200); 00336 trajectory_outcome_table_->setMinimumWidth(700); 00337 00338 r = 0; 00339 for(map<string, map<string, TrajectoryData> >::iterator it = trajectory_map_.begin(); 00340 it != trajectory_map_.end(); 00341 it++) { 00342 00343 for(map<string, TrajectoryData>::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++, r++) 00344 { 00345 QTableWidgetItem* motionPlanRequestItem = new QTableWidgetItem(QString::fromStdString(it->first)); 00346 motionPlanRequestItem->setFlags(Qt::ItemIsEnabled); 00347 trajectory_outcome_table_->setItem(r, 0, motionPlanRequestItem); 00348 00349 QTableWidgetItem* trajectoryItem = new QTableWidgetItem(QString::fromStdString(it2->first)); 00350 trajectoryItem->setFlags(Qt::ItemIsEnabled); 00351 trajectory_outcome_table_->setItem(r, 1, trajectoryItem); 00352 00353 QTableWidgetItem* sourceItem = new QTableWidgetItem(QString::fromStdString(it2->second.getSource())); 00354 sourceItem->setFlags(Qt::ItemIsEnabled); 00355 trajectory_outcome_table_->setItem(r, 2, sourceItem); 00356 00357 QTableWidgetItem* outcomeItem = new QTableWidgetItem(QString::fromStdString(armNavigationErrorCodeToString(it2->second.trajectory_error_code_))); 00358 outcomeItem ->setFlags(Qt::ItemIsEnabled); 00359 trajectory_outcome_table_->setItem(r, 3, outcomeItem); 00360 00361 if(it2->second.trajectory_error_code_.val != ArmNavigationErrorCodes::SUCCESS) 00362 { 00363 outcomeItem->setTextColor(QColor(150, 0, 0)); 00364 std::stringstream ss; 00365 ss << "Bad point: " << it2->second.getBadPoint(); 00366 outcomeItem->setToolTip(QString::fromStdString(ss.str())); 00367 } 00368 00369 } 00370 } 00371 layout->addWidget(stagesBox); 00372 layout->addWidget(trajectoryBox); 00373 outcome_dialog_->setLayout(layout); 00374 00375 } 00376 00377 void WarehouseViewer::viewOutcomesPressed() 00378 { 00379 createOutcomeDialog(); 00380 outcome_dialog_->exec(); 00381 delete outcome_dialog_; 00382 } 00383 00384 void WarehouseViewer::createAlterLinkPaddingDialog() 00385 { 00386 if(current_planning_scene_name_ == "") { 00387 return; 00388 } 00389 00390 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00391 00392 if(planning_scene.link_padding.size() == 0) { 00393 planning_environment::convertFromLinkPaddingMapToLinkPaddingVector(cm_->getDefaultLinkPaddingMap(), planning_scene.link_padding); 00394 planning_scene_map_[current_planning_scene_name_].setPlanningScene(planning_scene); 00395 } 00396 00397 alter_link_padding_dialog_ = new QDialog(this); 00398 alter_link_padding_dialog_->setWindowTitle("Alter Link Padding"); 00399 QVBoxLayout* layout = new QVBoxLayout(alter_link_padding_dialog_); 00400 00401 alter_link_padding_table_ = new QTableWidget(alter_link_padding_dialog_); 00402 QStringList alter_headers; 00403 alter_headers.append("Link name"); 00404 alter_headers.append("Padding (m)"); 00405 00406 alter_link_padding_table_->setColumnCount(2); 00407 alter_link_padding_table_->setRowCount((int)planning_scene.link_padding.size()); 00408 00409 alter_link_padding_table_->setHorizontalHeaderLabels(alter_headers); 00410 alter_link_padding_table_->setColumnWidth(0, 300); 00411 alter_link_padding_table_->setColumnWidth(1, 150); 00412 alter_link_padding_table_->setMinimumWidth(500); 00413 00414 for(unsigned int i = 0; i < planning_scene.link_padding.size(); i++) { 00415 QTableWidgetItem* link_item = new QTableWidgetItem(QString::fromStdString(planning_scene.link_padding[i].link_name)); 00416 link_item->setFlags(Qt::ItemIsEnabled); 00417 alter_link_padding_table_->setItem(i, 0, link_item); 00418 00419 QDoubleSpinBox* padding_spin_box = new QDoubleSpinBox(alter_link_padding_table_); 00420 padding_spin_box->setMinimum(0.0); 00421 padding_spin_box->setDecimals(3); 00422 padding_spin_box->setSingleStep(.005); 00423 padding_spin_box->setValue(planning_scene.link_padding[i].padding); 00424 connect(padding_spin_box, SIGNAL(valueChanged(double)), this, SLOT(alteredLinkPaddingValueChanged(double))); 00425 00426 alter_link_padding_table_->setCellWidget(i, 1, padding_spin_box); 00427 } 00428 layout->addWidget(alter_link_padding_table_); 00429 alter_link_padding_dialog_->setLayout(layout); 00430 } 00431 00432 void WarehouseViewer::alterLinkPaddingPressed() 00433 { 00434 createAlterLinkPaddingDialog(); 00435 alter_link_padding_dialog_->exec(); 00436 delete alter_link_padding_dialog_; 00437 } 00438 00439 void WarehouseViewer::alteredLinkPaddingValueChanged(double d) 00440 { 00441 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00442 planning_scene.link_padding.clear(); 00443 00444 for(int i = 0; i < alter_link_padding_table_->rowCount(); i++) 00445 { 00446 arm_navigation_msgs::LinkPadding lp; 00447 lp.link_name = alter_link_padding_table_->item(i,0)->text().toStdString(); 00448 lp.padding = dynamic_cast<QDoubleSpinBox*>(alter_link_padding_table_->cellWidget(i,1))->value(); 00449 planning_scene.link_padding.push_back(lp); 00450 } 00451 planning_scene_map_[current_planning_scene_name_].setPlanningScene(planning_scene); 00452 sendPlanningScene(planning_scene_map_[current_planning_scene_name_]); 00453 } 00454 00455 void WarehouseViewer::alterAllowedCollisionPressed() 00456 { 00457 createAlterAllowedCollisionDialog(); 00458 alter_allowed_collision_dialog_->exec(); 00459 delete alter_allowed_collision_dialog_; 00460 } 00461 00462 void WarehouseViewer::createAlterAllowedCollisionDialog() 00463 { 00464 if(current_planning_scene_name_ == "") { 00465 return; 00466 } 00467 00468 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00469 00470 if(planning_scene.allowed_collision_matrix.link_names.size() == 0) { 00471 planning_environment::convertFromACMToACMMsg(cm_->getDefaultAllowedCollisionMatrix(), planning_scene.allowed_collision_matrix); 00472 planning_scene_map_[current_planning_scene_name_].setPlanningScene(planning_scene); 00473 } 00474 00475 alter_allowed_collision_dialog_ = new QDialog(this); 00476 alter_allowed_collision_dialog_->setWindowTitle("Alter Allowed Collision"); 00477 00478 QGridLayout* layout = new QGridLayout(alter_allowed_collision_dialog_); 00479 00480 QLabel* col_1_label = new QLabel(alter_allowed_collision_dialog_); 00481 col_1_label->setText("First entity"); 00482 00483 QLabel* col_2_label = new QLabel(alter_allowed_collision_dialog_); 00484 col_2_label->setText("Second entity"); 00485 00486 QLabel* col_3_label = new QLabel(alter_allowed_collision_dialog_); 00487 col_3_label->setText("Status"); 00488 00489 QLabel* col_4_label = new QLabel(alter_allowed_collision_dialog_); 00490 col_4_label->setText("Operation"); 00491 00492 layout->addWidget(col_1_label, 0, 0); 00493 layout->addWidget(col_2_label, 0, 1); 00494 layout->addWidget(col_3_label, 0, 2); 00495 layout->addWidget(col_4_label, 0, 3); 00496 00497 first_allowed_collision_line_edit_ = new QLineEdit(alter_allowed_collision_dialog_); 00498 second_allowed_collision_line_edit_ = new QLineEdit(alter_allowed_collision_dialog_); 00499 00500 layout->addWidget(first_allowed_collision_line_edit_, 1, 0); 00501 layout->addWidget(second_allowed_collision_line_edit_, 1, 1); 00502 00503 connect(first_allowed_collision_line_edit_,SIGNAL(textEdited(const QString&)), this, SLOT(entityListsEdited())); 00504 connect(second_allowed_collision_line_edit_,SIGNAL(textEdited(const QString&)), this, SLOT(entityListsEdited())); 00505 00506 first_allowed_collision_list_ = new QListWidget(alter_allowed_collision_dialog_); 00507 second_allowed_collision_list_ = new QListWidget(alter_allowed_collision_dialog_); 00508 00509 for(unsigned int i = 0; i < planning_scene.allowed_collision_matrix.link_names.size(); i++) { 00510 if(cm_->getKinematicModel()->hasLinkModel(planning_scene.allowed_collision_matrix.link_names[i])) { 00511 first_allowed_collision_list_->addItem(planning_scene.allowed_collision_matrix.link_names[i].c_str()); 00512 second_allowed_collision_list_->addItem(planning_scene.allowed_collision_matrix.link_names[i].c_str()); 00513 } 00514 } 00515 addSpecialEntries(first_allowed_collision_list_); 00516 addSpecialEntries(second_allowed_collision_list_); 00517 00518 connect(first_allowed_collision_list_,SIGNAL(itemSelectionChanged()), this, SLOT(firstEntityListSelected())); 00519 connect(second_allowed_collision_list_,SIGNAL(itemSelectionChanged()), this, SLOT(secondEntityListSelected())); 00520 00521 00522 layout->addWidget(first_allowed_collision_list_, 2, 0); 00523 layout->addWidget(second_allowed_collision_list_, 2, 1); 00524 00525 allowed_status_line_edit_ = new QLineEdit(alter_allowed_collision_dialog_); 00526 allowed_status_line_edit_->setMinimumWidth(125); 00527 allowed_status_line_edit_->setMaximumWidth(125); 00528 allowed_status_line_edit_->setAlignment(Qt::AlignCenter); 00529 layout->addWidget(allowed_status_line_edit_, 1, 2); 00530 00531 QPushButton* enable_collision_button = new QPushButton(alter_allowed_collision_dialog_); 00532 enable_collision_button->setText("Enable"); 00533 enable_collision_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 00534 00535 QPushButton* disable_collision_button = new QPushButton(alter_allowed_collision_dialog_); 00536 disable_collision_button->setText("Disable"); 00537 disable_collision_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 00538 00539 connect(enable_collision_button, SIGNAL(clicked()), this, SLOT(enableCollisionClicked())); 00540 connect(disable_collision_button, SIGNAL(clicked()), this, SLOT(disableCollisionClicked())); 00541 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00542 00543 QPushButton* reset_default_button = new QPushButton(alter_allowed_collision_dialog_); 00544 reset_default_button->setText("Reset"); 00545 reset_default_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 00546 00547 connect(reset_default_button, SIGNAL(clicked()), this, SLOT(resetAllowedCollisionClicked())); 00548 00549 layout->addWidget(enable_collision_button, 1, 3); 00550 layout->addWidget(disable_collision_button, 2, 3, Qt::AlignTop); 00551 layout->addWidget(reset_default_button, 2, 3, Qt::AlignBottom); 00552 00553 alter_allowed_collision_dialog_->setLayout(layout); 00554 00555 alter_allowed_collision_dialog_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); 00556 } 00557 00558 void WarehouseViewer::addSpecialEntries(QListWidget* list_widget) { 00559 list_widget->addItem("------Groups---------"); 00560 std::vector<std::string> group_names; 00561 cm_->getKinematicModel()->getModelGroupNames(group_names); 00562 for(unsigned int i = 0; i < group_names.size(); i++) { 00563 list_widget->addItem(group_names[i].c_str()); 00564 } 00565 list_widget->addItem("------Objects---------"); 00566 std::vector<std::string> object_names; 00567 cm_->getCollisionObjectNames(object_names); 00568 for(unsigned int i = 0; i < object_names.size(); i++) { 00569 list_widget->addItem(object_names[i].c_str()); 00570 } 00571 list_widget->addItem("------Attached Objects---------"); 00572 std::vector<std::string> attached_object_names; 00573 cm_->getAttachedCollisionObjectNames(attached_object_names); 00574 for(unsigned int i = 0; i < attached_object_names.size(); i++) { 00575 list_widget->addItem(attached_object_names[i].c_str()); 00576 } 00577 list_widget->addItem("------Special-------"); 00578 list_widget->addItem("COLLISION_SET_ALL"); 00579 list_widget->addItem("COLLISION_SET_OBJECTS"); 00580 list_widget->addItem("COLLISION_SET_ATTACHED_OBJECTS"); 00581 } 00582 00583 void WarehouseViewer::getEntryList(const std::string& s1, 00584 std::vector<std::string>& sv1) 00585 { 00586 bool all = false; 00587 if(s1 == "COLLISION_SET_ALL") { 00588 all = true; 00589 } else if(s1 == "COLLISION_SET_OBJECTS") { 00590 cm_->getCollisionObjectNames(sv1); 00591 } else if(s1 == "COLLISION_SET_ATTACHED_OBJECTS") { 00592 cm_->getAttachedCollisionObjectNames(sv1); 00593 } else if(cm_->getKinematicModel()->hasModelGroup(s1)) { 00594 sv1 = cm_->getKinematicModel()->getModelGroup(s1)->getGroupLinkNames(); 00595 } else { 00596 sv1.push_back(s1); 00597 } 00598 if(all) { 00599 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getCurrentAllowedCollisionMatrix(); 00600 acm.getAllEntryNames(sv1); 00601 } 00602 } 00603 00604 void WarehouseViewer::resetAllowedCollisionClicked() 00605 { 00606 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00607 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getDefaultAllowedCollisionMatrix(); 00608 00609 planning_environment::convertFromACMToACMMsg(acm, planning_scene.allowed_collision_matrix); 00610 planning_scene_map_[current_planning_scene_name_].setPlanningScene(planning_scene); 00611 sendPlanningScene(planning_scene_map_[current_planning_scene_name_]); 00612 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00613 } 00614 00615 void WarehouseViewer::firstEntityListSelected() { 00616 first_allowed_collision_line_edit_->setText(first_allowed_collision_list_->selectedItems()[0]->text()); 00617 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00618 } 00619 00620 void WarehouseViewer::secondEntityListSelected() { 00621 second_allowed_collision_line_edit_->setText(second_allowed_collision_list_->selectedItems()[0]->text()); 00622 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00623 } 00624 00625 void WarehouseViewer::entityListsEdited() { 00626 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00627 } 00628 00629 void WarehouseViewer::enableCollisionClicked() { 00630 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00631 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = planning_environment::convertFromACMMsgToACM(planning_scene.allowed_collision_matrix); 00632 QString qs1 = first_allowed_collision_line_edit_->text(); 00633 QString qs2 = second_allowed_collision_line_edit_->text(); 00634 00635 std::vector<std::string> first_list; 00636 std::vector<std::string> second_list; 00637 00638 getEntryList(qs1.toStdString(), first_list); 00639 getEntryList(qs2.toStdString(), second_list); 00640 00641 bool all_enabled = true; 00642 00643 for(unsigned int i = 0; i < first_list.size(); i++) { 00644 for(unsigned int j = 0; j < second_list.size(); j++) { 00645 bool allowed = false; 00646 if(acm.getAllowedCollision(first_list[i], second_list[j], allowed)) { 00647 if(allowed) { 00648 all_enabled = false; 00649 break; 00650 } 00651 } 00652 } 00653 } 00654 if(all_enabled) return; 00655 00656 acm.changeEntry(first_list, second_list, false); 00657 planning_environment::convertFromACMToACMMsg(acm, planning_scene.allowed_collision_matrix); 00658 planning_scene_map_[current_planning_scene_name_].setPlanningScene(planning_scene); 00659 sendPlanningScene(planning_scene_map_[current_planning_scene_name_]); 00660 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00661 } 00662 00663 void WarehouseViewer::disableCollisionClicked() { 00664 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00665 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = planning_environment::convertFromACMMsgToACM(planning_scene.allowed_collision_matrix); 00666 QString qs1 = first_allowed_collision_line_edit_->text(); 00667 QString qs2 = second_allowed_collision_line_edit_->text(); 00668 00669 std::vector<std::string> first_list; 00670 std::vector<std::string> second_list; 00671 00672 getEntryList(qs1.toStdString(), first_list); 00673 getEntryList(qs2.toStdString(), second_list); 00674 00675 bool all_disabled = true; 00676 00677 for(unsigned int i = 0; i < first_list.size(); i++) { 00678 for(unsigned int j = 0; j < second_list.size(); j++) { 00679 bool allowed = false; 00680 if(acm.getAllowedCollision(first_list[i], second_list[j], allowed)) { 00681 if(!allowed) { 00682 all_disabled = false; 00683 break; 00684 } 00685 } 00686 } 00687 } 00688 00689 if(all_disabled) return; 00690 00691 acm.changeEntry(first_list, second_list, true); 00692 planning_environment::convertFromACMToACMMsg(acm, planning_scene.allowed_collision_matrix); 00693 planning_scene_map_[current_planning_scene_name_].setPlanningScene(planning_scene); 00694 sendPlanningScene(planning_scene_map_[current_planning_scene_name_]); 00695 setEnabledDisabledDisplay(first_allowed_collision_line_edit_->text(), second_allowed_collision_line_edit_->text()); 00696 } 00697 00698 void WarehouseViewer::setEnabledDisabledDisplay(const QString& qs1, const QString& qs2) { 00699 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 00700 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = planning_environment::convertFromACMMsgToACM(planning_scene.allowed_collision_matrix); 00701 std::vector<std::string> first_list; 00702 std::vector<std::string> second_list; 00703 00704 getEntryList(qs1.toStdString(), first_list); 00705 getEntryList(qs2.toStdString(), second_list); 00706 00707 bool all_disabled = true; 00708 bool all_enabled = true; 00709 bool some_found = false; 00710 00711 for(unsigned int i = 0; i < first_list.size(); i++) { 00712 for(unsigned int j = 0; j < second_list.size(); j++) { 00713 bool allowed = false; 00714 if(acm.getAllowedCollision(first_list[i], second_list[j], allowed)) { 00715 some_found = true; 00716 if(allowed) { 00717 all_enabled = false; 00718 } else { 00719 all_disabled = false; 00720 } 00721 } 00722 } 00723 } 00724 if(!some_found) { 00725 allowed_status_line_edit_->setText("NO ENTRY"); 00726 } else if(!all_disabled && !all_enabled) { 00727 allowed_status_line_edit_->setText("MIXED"); 00728 } else if(all_disabled) { 00729 allowed_status_line_edit_->setText("DISABLED"); 00730 } else { 00731 allowed_status_line_edit_->setText("ENABLED"); 00732 } 00733 } 00734 00735 void WarehouseViewer::refreshSceneButtonPressed() 00736 { 00737 if(current_planning_scene_name_ != "" ) 00738 { 00739 sendPlanningScene(planning_scene_map_[current_planning_scene_name_]); 00740 } 00741 else 00742 { 00743 QMessageBox msg(QMessageBox::Warning,"Refresh", "No planning scene loaded!"); 00744 msg.addButton(QMessageBox::Ok); 00745 msg.exec(); 00746 } 00747 } 00748 00749 void WarehouseViewer::executeButtonPressed() 00750 { 00751 if(selected_trajectory_name_ != "") 00752 { 00753 executeTrajectory(selected_motion_plan_name_, 00754 selected_trajectory_name_); 00755 } 00756 else 00757 { 00758 QMessageBox msg(QMessageBox::Warning, "Execute Trajectory", "No Trajectory Selected!"); 00759 msg.addButton("Ok", QMessageBox::AcceptRole); 00760 msg.exec(); 00761 } 00762 } 00763 00764 void WarehouseViewer::deleteSelectedMotionPlan() 00765 { 00766 if(selected_motion_plan_name_ != "") 00767 { 00768 lockScene(); 00769 std::vector<unsigned int> erased_trajectories; 00770 deleteMotionPlanRequest(motion_plan_map_[selected_motion_plan_name_].getId(), erased_trajectories); 00771 unlockScene(); 00772 } 00773 else 00774 { 00775 QMessageBox msg(QMessageBox::Warning, "Delete Motion Plan Request", "No Motion Plan Request Selected!"); 00776 msg.addButton("Ok", QMessageBox::AcceptRole); 00777 msg.exec(); 00778 } 00779 } 00780 00781 void WarehouseViewer::deleteSelectedTrajectory() 00782 { 00783 if(selected_trajectory_name_ != "") 00784 { 00785 lockScene(); 00786 unsigned int mpr_id = motion_plan_map_[selected_motion_plan_name_].getId(); 00787 unsigned int traj_id = trajectory_map_[selected_motion_plan_name_][selected_trajectory_name_].getId(); 00788 deleteTrajectory(mpr_id, 00789 traj_id); 00790 emit updateTables(); 00791 unlockScene(); 00792 } 00793 else 00794 { 00795 QMessageBox msg(QMessageBox::Warning, "Delete Trajectory", "No Trajectory Selected!"); 00796 msg.addButton("Ok", QMessageBox::AcceptRole); 00797 msg.exec(); 00798 } 00799 } 00800 00801 void WarehouseViewer::createNewMotionPlanPressed() 00802 { 00803 new_request_dialog_->open(); 00804 } 00805 00806 void WarehouseViewer::trajectoryEditChanged() 00807 { 00808 if(selected_trajectory_name_ != "") 00809 { 00810 TrajectoryData& trajectory = trajectory_map_[selected_motion_plan_name_][selected_trajectory_name_]; 00811 trajectory.setCurrentPoint(trajectory_point_edit_->value()); 00812 trajectory_slider_->setValue(trajectory_point_edit_->value()); 00813 } 00814 } 00815 00816 void WarehouseViewer::setupPlanningSceneDialog() 00817 { 00818 planning_scene_table_ = new QTableWidget(load_planning_scene_dialog_); 00819 QVBoxLayout* layout = new QVBoxLayout(load_planning_scene_dialog_); 00820 layout->addWidget(planning_scene_table_); 00821 load_scene_progress_ = new QProgressBar(load_planning_scene_dialog_); 00822 layout->addWidget(load_scene_progress_); 00823 00824 new_planning_scene_button_ = new QPushButton(load_planning_scene_dialog_); 00825 new_planning_scene_button_->setText("New..."); 00826 new_planning_scene_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00827 00828 load_planning_scene_button_ = new QPushButton(load_planning_scene_dialog_); 00829 load_planning_scene_button_->setText("Load..."); 00830 load_planning_scene_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00831 00832 remove_planning_scene_button_ = new QPushButton(load_planning_scene_dialog_); 00833 remove_planning_scene_button_->setText("Remove..."); 00834 remove_planning_scene_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00835 00836 refresh_planning_scene_button_ = new QPushButton(load_planning_scene_dialog_); 00837 refresh_planning_scene_button_->setText("Refresh..."); 00838 refresh_planning_scene_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00839 00840 connect(new_planning_scene_button_, SIGNAL(clicked()), this, SLOT(newButtonPressed())); 00841 connect(load_planning_scene_button_, SIGNAL(clicked()), this, SLOT(loadButtonPressed())); 00842 connect(refresh_planning_scene_button_, SIGNAL(clicked()), this, SLOT(refreshButtonPressed())); 00843 connect(remove_planning_scene_button_, SIGNAL(clicked()), this, SLOT(removePlanningSceneButtonPressed())); 00844 00845 load_motion_plan_requests_box_ = new QCheckBox(load_planning_scene_dialog_); 00846 load_motion_plan_requests_box_->setChecked(true); 00847 load_motion_plan_requests_box_->setText("Load Motion Plan Requests"); 00848 load_trajectories_box_ = new QCheckBox(load_planning_scene_dialog_); 00849 load_trajectories_box_->setChecked(true); 00850 load_trajectories_box_->setText("Load Trajectories"); 00851 00852 layout->addWidget(load_motion_plan_requests_box_); 00853 layout->addWidget(load_trajectories_box_); 00854 layout->addWidget(new_planning_scene_button_); 00855 layout->addWidget(load_planning_scene_button_); 00856 layout->addWidget(refresh_planning_scene_button_); 00857 layout->addWidget(remove_planning_scene_button_); 00858 00859 load_planning_scene_dialog_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 00860 load_planning_scene_dialog_->setLayout(layout); 00861 } 00862 00863 void WarehouseViewer::quit() 00864 { 00865 QMessageBox msgBox(QMessageBox::Warning, "Quit?", "Are you sure you want to quit? Unsaved changes will be lost."); 00866 QPushButton *quitButton = msgBox.addButton("Quit", QMessageBox::ActionRole); 00867 QPushButton *saveQuitButton = msgBox.addButton("Save And Quit", QMessageBox::ActionRole); 00868 msgBox.addButton(QMessageBox::Cancel); 00869 00870 msgBox.exec(); 00871 00872 if (msgBox.clickedButton() == quitButton) 00873 { 00874 quit_threads_ = true; 00875 delete this; 00876 return; 00877 } 00878 else if (msgBox.clickedButton() == saveQuitButton) 00879 { 00880 saveCurrentPlanningScene(false); 00881 quit_threads_ = true; 00882 delete this; 00883 return; 00884 } 00885 else 00886 { 00887 return; 00888 } 00889 } 00890 00891 void WarehouseViewer::motionPlanTableSelection() 00892 { 00893 QList<QTreeWidgetItem*> selected = motion_plan_tree_->selectedItems(); 00894 00895 if(selected.size() > 0) 00896 { 00897 const QString& name = selected[0]->toolTip(0); 00898 selectMotionPlan(name.toStdString()); 00899 } 00900 } 00901 00902 void WarehouseViewer::selectMotionPlan(std::string ID) 00903 { 00904 selected_motion_plan_name_ = ID; 00905 selected_trajectory_name_ = ""; 00906 createTrajectoryTable(); 00907 selected_request_label_->setText(QString::fromStdString("Selected Request: "+selected_motion_plan_name_ )); 00908 00909 00910 if(motion_plan_map_[selected_motion_plan_name_].getTrajectories().size() > 0) 00911 { 00912 unsigned int id = *(motion_plan_map_[selected_motion_plan_name_].getTrajectories().begin()); 00913 selectTrajectory(getTrajectoryNameFromId(id)); 00914 } 00915 } 00916 00917 void WarehouseViewer::createMotionPlanTable() 00918 { 00919 if(motion_plan_map_.find(selected_motion_plan_name_) == motion_plan_map_.end()) { 00920 selected_request_label_->setText("Selected Request: None"); 00921 selected_motion_plan_name_ = ""; 00922 } 00923 00924 if(current_planning_scene_name_ != "") 00925 { 00926 PlanningSceneData& planningSceneData = planning_scene_map_[current_planning_scene_name_]; 00927 00928 motion_plan_tree_->clear(); 00929 motion_plan_tree_->setColumnCount(4); 00930 motion_plan_tree_->setColumnWidth(0, 150); 00931 00932 unsigned int count = 0; 00933 for(std::set<unsigned int>::iterator it = planningSceneData.getRequests().begin(); 00934 it != planningSceneData.getRequests().end(); 00935 it++, count++) { 00936 00937 if(motion_plan_map_.find(getMotionPlanRequestNameFromId(*it)) == motion_plan_map_.end()) { 00938 ROS_INFO_STREAM("Bad matt 1"); 00939 } 00940 MotionPlanRequestData& requestData = motion_plan_map_[getMotionPlanRequestNameFromId(*it)]; 00941 00942 00943 QTreeWidgetItem* nameItem = new QTreeWidgetItem(QStringList(QString::fromStdString(requestData.getName()))); 00944 nameItem->setToolTip(0,nameItem->text(0)); 00945 nameItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 00946 motion_plan_tree_->insertTopLevelItem(count, nameItem); 00947 00948 QStringList sourceList; 00949 sourceList.append("Source"); 00950 sourceList.append(QString::fromStdString(requestData.getSource())); 00951 QTreeWidgetItem* sourceItem = new QTreeWidgetItem(sourceList); 00952 sourceItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 00953 sourceItem->setToolTip(0, nameItem->text(0)); 00954 sourceItem->setToolTip(1, nameItem->text(0)); 00955 nameItem->insertChild(0, sourceItem); 00956 00957 QStringList collisionList; 00958 collisionList.append("Collisions"); 00959 QTreeWidgetItem* collisionItem = new QTreeWidgetItem(collisionList); 00960 collisionItem->setToolTip(0, nameItem->text(0)); 00961 QCheckBox* collisionsVisible = new QCheckBox(motion_plan_tree_); 00962 collisionsVisible->setText("Show Collisions"); 00963 collisionsVisible->setToolTip(nameItem->text(0)); 00964 nameItem->insertChild(1, collisionItem); 00965 motion_plan_tree_->setItemWidget(collisionItem, 1, collisionsVisible); 00966 collisionsVisible->setChecked(requestData.areCollisionsVisible()); 00967 00968 connect(collisionsVisible, SIGNAL(clicked(bool)), this, SLOT(motionPlanCollisionVisibleButtonClicked(bool))); 00969 00970 QStringList startList; 00971 startList.append("Start Position"); 00972 startList.append(""); 00973 startList.append("Color"); 00974 startList.append(""); 00975 QTreeWidgetItem* startItem = new QTreeWidgetItem(startList); 00976 startItem->setToolTip(0, nameItem->text(0)); 00977 QCheckBox* startVisible = new QCheckBox(motion_plan_tree_); 00978 startVisible->setText("Visible"); 00979 startVisible->setToolTip(nameItem->text(0)); 00980 nameItem->insertChild(2, startItem); 00981 motion_plan_tree_->setItemWidget(startItem, 1, startVisible); 00982 startVisible->setChecked(requestData.isStartVisible()); 00983 00984 connect(startVisible, SIGNAL(clicked(bool)), this, SLOT(motionPlanStartVisibleButtonClicked(bool))); 00985 00986 QPushButton* startColorButton = new QPushButton(motion_plan_tree_); 00987 std::stringstream startColorStream; 00988 startColorStream<< "(" << (int)(requestData.getStartColor().r*255) <<" , "; 00989 startColorStream << (int)(requestData.getStartColor().g*255) << " , "; 00990 startColorStream << (int)(requestData.getStartColor().b*255) << ")"; 00991 startColorButton->setText(QString::fromStdString(startColorStream.str())); 00992 startColorButton->setToolTip(nameItem->text(0)); 00993 startColorButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 00994 connect(startColorButton, SIGNAL(clicked()), this, SLOT(motionPlanStartColorButtonClicked())); 00995 motion_plan_tree_->setItemWidget(startItem, 3, startColorButton); 00996 00997 00998 QStringList endList; 00999 endList.append("End Position"); 01000 endList.append(""); 01001 endList.append("Color"); 01002 endList.append(""); 01003 QTreeWidgetItem* endItem = new QTreeWidgetItem(endList); 01004 endItem->setToolTip(0, nameItem->text(0)); 01005 QCheckBox* endVisible = new QCheckBox(motion_plan_tree_); 01006 endVisible->setText("Visible"); 01007 endVisible->setToolTip(nameItem->text(0)); 01008 nameItem->insertChild(3, endItem); 01009 motion_plan_tree_->setItemWidget(endItem, 1, endVisible); 01010 endVisible->setChecked(requestData.isEndVisible()); 01011 01012 connect(endVisible, SIGNAL(clicked(bool)), this, SLOT(motionPlanEndVisibleButtonClicked(bool))); 01013 01014 QPushButton* endColorButton = new QPushButton(motion_plan_tree_); 01015 std::stringstream endColorStream; 01016 endColorStream<< "(" << (int)(requestData.getGoalColor().r*255) <<" , "; 01017 endColorStream << (int)(requestData.getGoalColor().g*255) << " , "; 01018 endColorStream << (int)(requestData.getGoalColor().b*255) << ")"; 01019 endColorButton->setText(QString::fromStdString(endColorStream.str())); 01020 endColorButton->setToolTip(nameItem->text(0)); 01021 endColorButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01022 connect(endColorButton, SIGNAL(clicked()), this, SLOT(motionPlanEndColorButtonClicked())); 01023 motion_plan_tree_->setItemWidget(endItem, 3, endColorButton); 01024 01025 QStringList controlList; 01026 controlList.append("Joint Control"); 01027 QTreeWidgetItem* controlItem = new QTreeWidgetItem(controlList); 01028 controlItem->setToolTip(0, nameItem->text(0)); 01029 nameItem->insertChild(4, controlItem); 01030 QCheckBox* controlsVisible = new QCheckBox(motion_plan_tree_); 01031 controlsVisible->setText("Joint Control"); 01032 controlsVisible->setToolTip(nameItem->text(0)); 01033 connect(controlsVisible, SIGNAL(clicked(bool)), this, SLOT(motionPlanJointControlsActiveButtonClicked(bool))); 01034 motion_plan_tree_->setItemWidget(controlItem,1, controlsVisible); 01035 01036 QStringList renderTypeList; 01037 renderTypeList.append("Render Mode"); 01038 QTreeWidgetItem* renderTypeItem = new QTreeWidgetItem(renderTypeList); 01039 renderTypeItem->setToolTip(0, nameItem->text(0)); 01040 01041 QComboBox* renderTypeBox = new QComboBox(motion_plan_tree_); 01042 QStringList items; 01043 items.append("Collision Mesh"); 01044 items.append("Visual Mesh"); 01045 items.append("Padding Mesh"); 01046 renderTypeBox->addItems(items); 01047 connect(renderTypeBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(motionPlanRenderTypeChanged(const QString&))); 01048 renderTypeBox->setToolTip(nameItem->text(0)); 01049 nameItem->insertChild(5, renderTypeItem); 01050 motion_plan_tree_->setItemWidget(renderTypeItem, 1, renderTypeBox); 01051 01052 switch(requestData.getRenderType()) 01053 { 01054 case CollisionMesh: 01055 renderTypeBox->setCurrentIndex(0); 01056 break; 01057 case VisualMesh: 01058 renderTypeBox->setCurrentIndex(1); 01059 break; 01060 case PaddingMesh: 01061 renderTypeBox->setCurrentIndex(2); 01062 break; 01063 } 01064 } 01065 } 01066 } 01067 01068 void WarehouseViewer::motionPlanCollisionVisibleButtonClicked(bool checked) 01069 { 01070 QObject* sender = QObject::sender(); 01071 QCheckBox* button = qobject_cast<QCheckBox*> (sender); 01072 01073 if(button != NULL) 01074 { 01075 std::string mprID = button->toolTip().toStdString(); 01076 MotionPlanRequestData& data = motion_plan_map_[mprID]; 01077 data.setCollisionsVisible(checked); 01078 } 01079 } 01080 01081 void WarehouseViewer::motionPlanStartColorButtonClicked() 01082 { 01083 QObject* sender = QObject::sender(); 01084 QPushButton* button = qobject_cast<QPushButton*>(sender); 01085 01086 if(button != NULL) 01087 { 01088 std::string trajectoryID = button->toolTip().toStdString(); 01089 MotionPlanRequestData& data = motion_plan_map_[trajectoryID]; 01090 QColor col(data.getStartColor().r*255, data.getStartColor().g*255, data.getStartColor().b*255); 01091 QColor colorSelected = QColorDialog::getColor(col, this); 01092 if(!colorSelected.isValid()) 01093 { 01094 return; 01095 } 01096 std::stringstream colorStream; 01097 colorStream<< "(" << colorSelected.red()<<" , "; 01098 colorStream << colorSelected.green()<< " , "; 01099 colorStream << colorSelected.blue() << ")"; 01100 01101 button->setText(QString::fromStdString(colorStream.str())); 01102 01103 std_msgs::ColorRGBA trajColor; 01104 trajColor.r = colorSelected.redF(); 01105 trajColor.g = colorSelected.greenF(); 01106 trajColor.b = colorSelected.blueF(); 01107 trajColor.a = 0.5f; 01108 data.setStartColor(trajColor); 01109 data.refreshColors(); 01110 } 01111 } 01112 01113 void WarehouseViewer::motionPlanEndColorButtonClicked() 01114 { 01115 QObject* sender = QObject::sender(); 01116 QPushButton* button = qobject_cast<QPushButton*>(sender); 01117 01118 if(button != NULL) 01119 { 01120 std::string trajectoryID = button->toolTip().toStdString(); 01121 MotionPlanRequestData& data = motion_plan_map_[trajectoryID]; 01122 QColor col(data.getGoalColor().r*255, data.getGoalColor().g*255, data.getGoalColor().b*255); 01123 QColor colorSelected = QColorDialog::getColor(col, this); 01124 if(!colorSelected.isValid()) 01125 { 01126 return; 01127 } 01128 std::stringstream colorStream; 01129 colorStream<< "(" << colorSelected.red()<<" , "; 01130 colorStream << colorSelected.green()<< " , "; 01131 colorStream << colorSelected.blue() << ")"; 01132 01133 button->setText(QString::fromStdString(colorStream.str())); 01134 01135 std_msgs::ColorRGBA trajColor; 01136 trajColor.r = colorSelected.redF(); 01137 trajColor.g = colorSelected.greenF(); 01138 trajColor.b = colorSelected.blueF(); 01139 trajColor.a = 0.5f; 01140 data.setGoalColor(trajColor); 01141 data.refreshColors(); 01142 01143 } 01144 } 01145 01146 void WarehouseViewer::motionPlanStartVisibleButtonClicked(bool checked) 01147 { 01148 QObject* sender = QObject::sender(); 01149 QCheckBox* button = qobject_cast<QCheckBox*> (sender); 01150 01151 if(button != NULL) 01152 { 01153 std::string mprID = button->toolTip().toStdString(); 01154 MotionPlanRequestData& data = motion_plan_map_[mprID]; 01155 data.setStartVisible(checked); 01156 data.setJointControlsVisible(data.areJointControlsVisible(), this); 01157 setIKControlsVisible(mprID, StartPosition, button->isChecked()); 01158 } 01159 01160 01161 } 01162 01163 void WarehouseViewer::motionPlanEndVisibleButtonClicked(bool checked) 01164 { 01165 QObject* sender = QObject::sender(); 01166 QCheckBox* button = qobject_cast<QCheckBox*> (sender); 01167 01168 if(button != NULL) 01169 { 01170 std::string mprID = button->toolTip().toStdString(); 01171 MotionPlanRequestData& data = motion_plan_map_[mprID]; 01172 data.setEndVisible(checked); 01173 data.setJointControlsVisible(data.areJointControlsVisible(), this); 01174 setIKControlsVisible(mprID, GoalPosition, button->isChecked()); 01175 } 01176 } 01177 01178 void WarehouseViewer::createNewMotionPlanRequest(std::string group_name, std::string end_effector_name) 01179 { 01180 01181 if(current_planning_scene_name_ != "") 01182 { 01183 unsigned int motion_plan_id; 01184 createMotionPlanRequest(*robot_state_, *robot_state_, 01185 group_name, end_effector_name, false, 01186 getPlanningSceneIdFromName(current_planning_scene_name_), 01187 create_request_from_robot_box_->isChecked(), 01188 motion_plan_id); 01189 selectMotionPlan(getMotionPlanRequestNameFromId(motion_plan_id)); 01190 } 01191 else 01192 { 01193 QMessageBox msg(QMessageBox::Warning, "Create Request", "No Planning Scene Loaded!"); 01194 msg.addButton("Ok", QMessageBox::AcceptRole); 01195 msg.exec(); 01196 } 01197 } 01198 01199 void WarehouseViewer::savePlanningSceneSlot() { 01200 saveCurrentPlanningScene(false); 01201 } 01202 01203 void WarehouseViewer::copyPlanningSceneSlot() { 01204 saveCurrentPlanningScene(true); 01205 trajectory_tree_->clear(); 01206 updateJointStates(); 01207 createMotionPlanTable(); 01208 planning_scene_map_[current_planning_scene_name_].getRobotState(robot_state_); 01209 } 01210 01211 void WarehouseViewer::saveCurrentPlanningScene(bool copy) 01212 { 01213 ROS_DEBUG_STREAM("Current planning scene id is " << current_planning_scene_name_); 01214 ROS_DEBUG_STREAM("Hostname is " << planning_scene_map_[current_planning_scene_name_].getHostName()); 01215 savePlanningScene(planning_scene_map_[current_planning_scene_name_], copy); 01216 QMessageBox msgBox(QMessageBox::Information, "Saved", "Saved planning scene successfully."); 01217 msgBox.addButton(QMessageBox::Ok); 01218 msgBox.exec(); 01219 } 01220 01221 void WarehouseViewer::createNewPlanningSceneSlot() { 01222 createNewPlanningSceneConfirm(); 01223 } 01224 01225 bool WarehouseViewer::createNewPlanningSceneConfirm() 01226 { 01227 if(planning_scene_initialized_) { 01228 QMessageBox msgBox(QMessageBox::Warning, "Create New Planning Scene", "Are you sure you want to create a new planning scene? Unsaved changes to the current planning scene will be lost."); 01229 QPushButton *createButton= msgBox.addButton("Create New Without Saving Changes", QMessageBox::ActionRole); 01230 QPushButton *saveCreateButton = msgBox.addButton("Save Changes Before Creating New", QMessageBox::ActionRole); 01231 msgBox.addButton(QMessageBox::Cancel); 01232 01233 msgBox.exec(); 01234 if (msgBox.clickedButton() == saveCreateButton) 01235 { 01236 saveCurrentPlanningScene(false); 01237 setCurrentPlanningScene(createNewPlanningScene(), true, true); 01238 motion_plan_tree_->clear(); 01239 trajectory_tree_->clear(); 01240 ROS_INFO("Created a new planning scene: %s", current_planning_scene_name_.c_str()); 01241 } 01242 else if (msgBox.clickedButton() != createButton) 01243 { 01244 return false; 01245 } 01246 } 01247 setCurrentPlanningScene(createNewPlanningScene(), true, true); 01248 planning_scene_initialized_ = true; 01249 motion_plan_tree_->clear(); 01250 trajectory_tree_->clear(); 01251 ROS_INFO("Created a new planning scene: %s", current_planning_scene_name_.c_str()); 01252 return true; 01253 } 01254 01255 void WarehouseViewer::updateState() 01256 { 01257 emit updateTables(); 01258 } 01259 01260 void WarehouseViewer::updateStateTriggered() 01261 { 01262 lockScene(); 01263 createMotionPlanTable(); 01264 createTrajectoryTable(); 01265 unlockScene(); 01266 } 01267 01268 void WarehouseViewer::primaryPlannerTriggered() 01269 { 01270 if(set_primary_planner_action_->isChecked()) { 01271 set_secondary_planner_action_->setChecked(false); 01272 use_interpolated_planner_ = false; 01273 } else if(!set_secondary_planner_action_->isChecked()){ 01274 set_primary_planner_action_->setChecked(true); 01275 } 01276 } 01277 01278 void WarehouseViewer::secondaryPlannerTriggered() 01279 { 01280 if(set_secondary_planner_action_->isChecked()) { 01281 set_primary_planner_action_->setChecked(false); 01282 use_interpolated_planner_ = true; 01283 } else if(!set_primary_planner_action_->isChecked()){ 01284 set_secondary_planner_action_->setChecked(true); 01285 } 01286 } 01287 01288 void WarehouseViewer::popupLoadPlanningScenes() 01289 { 01290 if(!warehouse_data_loaded_once_) 01291 { 01292 refreshButtonPressed(); 01293 } 01294 load_planning_scene_dialog_->exec(); 01295 } 01296 01297 void WarehouseViewer::refreshButtonPressed() 01298 { 01299 if(table_load_thread_ != NULL) 01300 { 01301 table_load_thread_->wait(); 01302 delete table_load_thread_; 01303 table_load_thread_ = NULL; 01304 } 01305 table_load_thread_= new TableLoadThread(this); 01306 table_load_thread_->start(); 01307 } 01308 01309 void WarehouseViewer::newButtonPressed() 01310 { 01311 if(createNewPlanningSceneConfirm()) { 01312 load_planning_scene_dialog_->close(); 01313 } 01314 } 01315 01316 void WarehouseViewer::loadButtonPressed() 01317 { 01318 if(planning_scene_initialized_) { 01319 QMessageBox msgBox(QMessageBox::Information, "Load New Planning Scene", "Are you sure you want to load a new planning scene? Unsaved changes to the current planning scene will be lost."); 01320 QPushButton *createButton= msgBox.addButton("Load New Without Saving Changes", QMessageBox::ActionRole); 01321 QPushButton *saveCreateButton = msgBox.addButton("Save Changes Before Loading New", QMessageBox::ActionRole); 01322 msgBox.addButton(QMessageBox::Cancel); 01323 01324 msgBox.exec(); 01325 01326 if (msgBox.clickedButton() == saveCreateButton) 01327 { 01328 saveCurrentPlanningScene(false); 01329 } 01330 else if (msgBox.clickedButton() != createButton) 01331 { 01332 return; 01333 } 01334 } 01335 01336 QList<QTableWidgetItem*> items = planning_scene_table_->selectedItems(); 01337 01338 if(items.size() > 0) 01339 { 01340 QTableWidgetItem* item = items[0]; 01341 QTableWidgetItem* nameItem = planning_scene_table_->item(item->row(),1); 01342 PlanningSceneData& data = planning_scene_map_[nameItem->text().toStdString()]; 01343 loadPlanningScene(data.getTimeStamp(), data.getId()); 01344 //this will blow away the above reference, so redoing 01345 data = planning_scene_map_[nameItem->text().toStdString()]; 01346 setCurrentPlanningScene(nameItem->text().toStdString(), load_motion_plan_requests_box_->isChecked(), load_trajectories_box_->isChecked()); 01347 trajectory_tree_->clear(); 01348 updateJointStates(); 01349 createMotionPlanTable(); 01350 data.getRobotState(robot_state_); 01351 planning_scene_initialized_ = true; 01352 load_planning_scene_dialog_->close(); 01353 } 01354 } 01355 01356 void WarehouseViewer::removePlanningSceneButtonPressed() 01357 { 01358 QMessageBox msgBox(QMessageBox::Information, "Remove Planning Scene", "This will permanently remove the indicated planning scene(s) and all associated data from the warehouse."); 01359 msgBox.addButton(QMessageBox::Cancel); 01360 01361 QPushButton *deleteButton= msgBox.addButton("Remove", QMessageBox::ActionRole); 01362 01363 msgBox.exec(); 01364 01365 if (msgBox.clickedButton() != deleteButton) 01366 { 01367 return; 01368 } 01369 01370 QList<QTableWidgetItem*> items = planning_scene_table_->selectedItems(); 01371 01372 for(int i = 0; i < items.size(); i++) { 01373 QTableWidgetItem* item = items[i]; 01374 QTableWidgetItem* nameItem = planning_scene_table_->item(item->row(),1); 01375 PlanningSceneData& data = planning_scene_map_[nameItem->text().toStdString()]; 01376 move_arm_warehouse_logger_reader_->removePlanningSceneAndAssociatedDataFromWarehouse(data.getHostName(), data.getId()); 01377 planning_scene_map_.erase(nameItem->text().toStdString()); 01378 planning_scene_table_->removeRow(item->row()); 01379 } 01380 } 01381 01382 void WarehouseViewer::replanButtonPressed() 01383 { 01384 if(selected_motion_plan_name_ != "") 01385 { 01386 unsigned int new_traj; 01387 planToRequest(motion_plan_map_[selected_motion_plan_name_], new_traj); 01388 createTrajectoryTable(); 01389 selectTrajectory(getTrajectoryNameFromId(new_traj)); 01390 playTrajectory(motion_plan_map_[selected_motion_plan_name_], 01391 trajectory_map_[selected_motion_plan_name_][getTrajectoryNameFromId(new_traj)]); 01392 } 01393 else 01394 { 01395 QMessageBox msg(QMessageBox::Warning, "Plan Trajectory", "No Motion Plan Request Selected!"); 01396 msg.addButton("Ok", QMessageBox::AcceptRole); 01397 msg.exec(); 01398 } 01399 } 01400 01401 void WarehouseViewer::trajectoryTableSelection() 01402 { 01403 QList<QTreeWidgetItem*> selected = trajectory_tree_->selectedItems(); 01404 01405 if(selected.size() > 0) 01406 { 01407 QString name = selected[0]->toolTip(0); 01408 selectTrajectory(name.toStdString()); 01409 } 01410 } 01411 01412 void WarehouseViewer::selectTrajectory(std::string ID) 01413 { 01414 if(ID == "") { 01415 ROS_WARN_STREAM("Empty trajectory being selected - that's bad"); 01416 return; 01417 } 01418 selected_trajectory_name_ = ID; 01419 TrajectoryData& trajectory = trajectory_map_[selected_motion_plan_name_][selected_trajectory_name_]; 01420 unsigned int point = trajectory.getCurrentPoint(); 01421 int sz = ((int)trajectory.getTrajectory().points.size()) - 1; 01422 trajectory_slider_->setMaximum(sz); 01423 trajectory_slider_->setMinimum(0); 01424 trajectory_slider_->setValue(point); 01425 01426 trajectory_point_edit_->setRange(0,sz); 01427 trajectory_point_edit_->setValue(point); 01428 01429 std::stringstream ss; 01430 ss << trajectory.trajectory_error_code_.val; 01431 selected_trajectory_label_->setText(QString::fromStdString(ID + " Error Code : " + armNavigationErrorCodeToString(trajectory.trajectory_error_code_) + " (" + ss.str().c_str()+ ")")); 01432 } 01433 01434 void WarehouseViewer::playButtonPressed() 01435 { 01436 if(selected_trajectory_name_ != "") 01437 { 01438 TrajectoryData& trajectory = trajectory_map_[selected_motion_plan_name_][selected_trajectory_name_]; 01439 playTrajectory(motion_plan_map_[getMotionPlanRequestNameFromId(trajectory.getMotionPlanRequestId())], 01440 trajectory); 01441 std::stringstream ss; 01442 ss << trajectory.trajectory_error_code_.val; 01443 selected_trajectory_label_->setText(QString::fromStdString(selected_trajectory_name_ + " Error Code : " + armNavigationErrorCodeToString(trajectory.trajectory_error_code_) + " (" + ss.str().c_str()+ ")")); 01444 01445 // Set checkbox to visible. 01446 for(int i = 0; i < trajectory_tree_->topLevelItemCount(); i++) 01447 { 01448 QTreeWidgetItem* item = trajectory_tree_->topLevelItem(i); 01449 01450 if(item->text(0).toStdString() == selected_trajectory_name_) 01451 { 01452 for(int j = 0; j < item->childCount(); j++) 01453 { 01454 QTreeWidgetItem* child = item->child(j); 01455 QCheckBox* box = dynamic_cast<QCheckBox*>(trajectory_tree_->itemWidget(child, 0)); 01456 01457 if(box != NULL) 01458 { 01459 if(box->text().toStdString() == "Visible") 01460 { 01461 box->setChecked(true); 01462 break; 01463 } 01464 } 01465 } 01466 break; 01467 } 01468 } 01469 01470 } 01471 else 01472 { 01473 QMessageBox msg(QMessageBox::Warning, "Play Trajectory", "No Trajectory Selected!"); 01474 msg.addButton("Ok", QMessageBox::AcceptRole); 01475 msg.exec(); 01476 } 01477 } 01478 01479 void WarehouseViewer::filterButtonPressed() 01480 { 01481 if(selected_trajectory_name_ != "") 01482 { 01483 TrajectoryData& trajectory = trajectory_map_[selected_motion_plan_name_][selected_trajectory_name_]; 01484 unsigned int filterID; 01485 MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(trajectory.getMotionPlanRequestId())]; 01486 filterTrajectory(data,trajectory, filterID); 01487 playTrajectory(data, trajectory_map_[selected_motion_plan_name_][getTrajectoryNameFromId(filterID)]); 01488 std::stringstream ss; 01489 ss << trajectory.trajectory_error_code_.val; 01490 selected_trajectory_label_->setText(QString::fromStdString(selected_trajectory_name_ + " Error Code : " + armNavigationErrorCodeToString(trajectory.trajectory_error_code_) + " (" + ss.str().c_str()+ ")")); 01491 createTrajectoryTable(); 01492 } 01493 else 01494 { 01495 QMessageBox msg(QMessageBox::Warning, "Filter Trajectory", "No Trajectory Selected!"); 01496 msg.addButton("Ok", QMessageBox::AcceptRole); 01497 msg.exec(); 01498 } 01499 } 01500 01501 void WarehouseViewer::sliderDragged(int nv) 01502 { 01503 if(selected_trajectory_name_ != "") 01504 { 01505 trajectory_point_edit_->setValue(nv); 01506 } 01507 else 01508 { 01509 QMessageBox msg(QMessageBox::Warning, "Control Trajectory", "No Trajectory Selected!"); 01510 msg.addButton("Ok", QMessageBox::AcceptRole); 01511 msg.exec(); 01512 } 01513 } 01514 01515 void WarehouseViewer::createTrajectoryTable() 01516 { 01517 if(selected_motion_plan_name_ == "") 01518 { 01519 trajectory_tree_->clear(); 01520 trajectory_tree_->setColumnCount(2); 01521 trajectory_tree_->setColumnWidth(0, 200); 01522 selected_trajectory_name_ = ""; 01523 selected_trajectory_label_->setText("None"); 01524 trajectory_slider_->setMaximum(0); 01525 trajectory_slider_->setMinimum(0); 01526 trajectory_point_edit_->setRange(0,0); 01527 return; 01528 } 01529 01530 if(!hasTrajectory(selected_motion_plan_name_, 01531 selected_trajectory_name_)) { 01532 selected_trajectory_name_ = ""; 01533 selected_trajectory_label_->setText("None"); 01534 trajectory_slider_->setMaximum(0); 01535 trajectory_slider_->setMinimum(0); 01536 trajectory_point_edit_->setRange(0,0); 01537 } else { 01538 selectTrajectory(selected_trajectory_name_); 01539 } 01540 01541 if(motion_plan_map_.find(selected_motion_plan_name_) == motion_plan_map_.end()) { 01542 ROS_INFO_STREAM("Going to be generating empty MPR"); 01543 } 01544 01545 MotionPlanRequestData& data = motion_plan_map_[selected_motion_plan_name_]; 01546 trajectory_tree_->clear(); 01547 trajectory_tree_->setColumnCount(2); 01548 trajectory_tree_->setColumnWidth(0, 200); 01549 01550 unsigned int count = 0; 01551 for(std::set<unsigned int>::iterator it = data.getTrajectories().begin(); 01552 it != data.getTrajectories().end(); 01553 it++, count++) { 01554 TrajectoryData& trajectory = 01555 trajectory_map_[selected_motion_plan_name_][getTrajectoryNameFromId(*it)]; 01556 01557 QTreeWidgetItem* nameItem = new QTreeWidgetItem(QStringList(QString::fromStdString(trajectory.getName()))); 01558 nameItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01559 nameItem->setToolTip(0, nameItem->text(0)); 01560 trajectory_tree_->insertTopLevelItem(count, nameItem); 01561 01562 QStringList sourceList; 01563 sourceList.append("Source"); 01564 sourceList.append(QStringList(QString::fromStdString(trajectory.getSource()))); 01565 QTreeWidgetItem* sourceItem = new QTreeWidgetItem(sourceList); 01566 sourceItem->setToolTip(0, nameItem->text(0)); 01567 sourceItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01568 nameItem->insertChild(0, sourceItem); 01569 01570 std::stringstream durationStream; 01571 durationStream << (float)trajectory.getDuration().toSec() << " seconds"; 01572 01573 QStringList durationList; 01574 if(trajectory.getSource() == "Planner" || trajectory.getSource() == "planner") 01575 { 01576 durationList.append("Planning Time"); 01577 } 01578 else if (trajectory.getSource() == "Trajectory Filterer" || trajectory.getSource() == "filter") 01579 { 01580 durationList.append("Filter Time"); 01581 } 01582 else if(trajectory.getSource() == "Robot Monitor" || trajectory.getSource() == "monitor") 01583 { 01584 durationList.append("Execution Time"); 01585 } 01586 else 01587 { 01588 durationList.append("Duration"); 01589 } 01590 durationList.append(QString::fromStdString(durationStream.str())); 01591 QTreeWidgetItem* durationItem = new QTreeWidgetItem(durationList); 01592 durationItem->setToolTip(0, nameItem->text(0)); 01593 durationItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01594 nameItem->insertChild(1, durationItem); 01595 01596 QStringList collisionList; 01597 collisionList.append(""); 01598 QTreeWidgetItem* collisionItem = new QTreeWidgetItem(collisionList); 01599 collisionItem->setToolTip(0, nameItem->text(0)); 01600 QCheckBox* collisionsVisibleBox = new QCheckBox(trajectory_tree_); 01601 collisionsVisibleBox->setText("Show Collisions"); 01602 collisionsVisibleBox->setChecked(trajectory.areCollisionsVisible()); 01603 collisionsVisibleBox->setToolTip(nameItem->text(0)); 01604 nameItem->insertChild(2, collisionItem); 01605 trajectory_tree_->setItemWidget(collisionItem, 0, collisionsVisibleBox); 01606 connect(collisionsVisibleBox, SIGNAL(clicked(bool)), this, SLOT(trajectoryCollisionsVisibleButtonClicked(bool))); 01607 01608 QStringList visibleList; 01609 visibleList.append(""); 01610 QTreeWidgetItem* visibleItem = new QTreeWidgetItem(visibleList); 01611 visibleItem->setToolTip(0, nameItem->text(0)); 01612 QCheckBox* visibleBox = new QCheckBox(trajectory_tree_); 01613 visibleBox->setText("Visible"); 01614 visibleBox->setChecked(trajectory.isVisible()); 01615 nameItem->insertChild(3, visibleItem); 01616 trajectory_tree_->setItemWidget(visibleItem, 0, visibleBox); 01617 visibleBox->setToolTip(nameItem->text(0)); 01618 connect(visibleBox, SIGNAL(clicked(bool)), this, SLOT(trajectoryVisibleButtonClicked(bool))); 01619 01620 QStringList colorList; 01621 colorList.append("Color"); 01622 colorList.append(""); 01623 QTreeWidgetItem* colorItem = new QTreeWidgetItem(colorList); 01624 colorItem->setToolTip(0, nameItem->text(0)); 01625 QPushButton* colorButton = new QPushButton(trajectory_tree_); 01626 01627 std::stringstream colorStream; 01628 colorStream<< "(" << (int)(trajectory.getColor().r*255) <<" , "; 01629 colorStream << (int)(trajectory.getColor().g*255) << " , "; 01630 colorStream << (int)(trajectory.getColor().b*255) << ")"; 01631 01632 colorButton->setText(QString::fromStdString(colorStream.str())); 01633 colorButton->setToolTip(nameItem->text(0)); 01634 colorButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 01635 connect(colorButton, SIGNAL(clicked()), this, SLOT(trajectoryColorButtonClicked())); 01636 01637 nameItem->insertChild(4, colorItem); 01638 trajectory_tree_->setItemWidget(colorItem, 1, colorButton); 01639 01640 QStringList renderTypeList; 01641 renderTypeList.append("Render Mode"); 01642 QTreeWidgetItem* renderTypeItem = new QTreeWidgetItem(renderTypeList); 01643 renderTypeItem->setToolTip(0, nameItem->text(0)); 01644 01645 QComboBox* renderTypeBox = new QComboBox(trajectory_tree_); 01646 QStringList items; 01647 items.append("Collision Mesh"); 01648 items.append("Visual Mesh"); 01649 items.append("Padding Mesh"); 01650 renderTypeBox->addItems(items); 01651 renderTypeBox->setToolTip(nameItem->text(0)); 01652 connect(renderTypeBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(trajectoryRenderTypeChanged(const QString&))); 01653 01654 nameItem->insertChild(5, renderTypeItem); 01655 trajectory_tree_->setItemWidget(renderTypeItem, 1, renderTypeBox); 01656 01657 switch(trajectory.getRenderType()) 01658 { 01659 case CollisionMesh: 01660 renderTypeBox->setCurrentIndex(0); 01661 break; 01662 case VisualMesh: 01663 renderTypeBox->setCurrentIndex(1); 01664 break; 01665 case PaddingMesh: 01666 renderTypeBox->setCurrentIndex(2); 01667 break; 01668 } 01669 } 01670 01671 } 01672 01673 void WarehouseViewer::trajectoryCollisionsVisibleButtonClicked(bool checked) 01674 { 01675 QObject* sender = QObject::sender(); 01676 QCheckBox* button = qobject_cast<QCheckBox*> (sender); 01677 01678 if(button != NULL) 01679 { 01680 std::string trajectoryID = button->toolTip().toStdString(); 01681 TrajectoryData& data = trajectory_map_[selected_motion_plan_name_][trajectoryID]; 01682 data.setCollisionsVisible(checked); 01683 } 01684 } 01685 01686 void WarehouseViewer::trajectoryVisibleButtonClicked(bool checked) 01687 { 01688 QObject* sender = QObject::sender(); 01689 QCheckBox* button = qobject_cast<QCheckBox*> (sender); 01690 01691 if(button != NULL) 01692 { 01693 std::string trajectoryID = button->toolTip().toStdString(); 01694 TrajectoryData& data = trajectory_map_[selected_motion_plan_name_][trajectoryID]; 01695 data.setVisible(checked); 01696 } 01697 } 01698 01699 void WarehouseViewer::trajectoryColorButtonClicked() 01700 { 01701 QObject* sender = QObject::sender(); 01702 QPushButton* button = qobject_cast<QPushButton*>(sender); 01703 01704 if(button != NULL) 01705 { 01706 std::string trajectoryID = button->toolTip().toStdString(); 01707 TrajectoryData& data = trajectory_map_[selected_motion_plan_name_][trajectoryID]; 01708 QColor col(data.getColor().r*255, data.getColor().g*255, data.getColor().b*255); 01709 QColor colorSelected = QColorDialog::getColor(col, this); 01710 if(!colorSelected.isValid()) 01711 { 01712 return; 01713 } 01714 std::stringstream colorStream; 01715 colorStream<< "(" << colorSelected.red()<<" , "; 01716 colorStream << colorSelected.green()<< " , "; 01717 colorStream << colorSelected.blue() << ")"; 01718 01719 button->setText(QString::fromStdString(colorStream.str())); 01720 01721 std_msgs::ColorRGBA trajColor; 01722 trajColor.r = colorSelected.redF(); 01723 trajColor.g = colorSelected.greenF(); 01724 trajColor.b = colorSelected.blueF(); 01725 trajColor.a = 0.5f; 01726 data.setColor(trajColor); 01727 data.refreshColors(); 01728 } 01729 } 01730 01731 void WarehouseViewer::onPlanningSceneLoaded(int scene, int numScenes) 01732 { 01733 emit changeProgress((int)((100.0f)*((float)(scene + 1)/ (float)numScenes))); 01734 } 01735 01736 void WarehouseViewer::createPlanningSceneTable() 01737 { 01738 loadAllWarehouseData(); 01739 warehouse_data_loaded_once_ = true; 01740 planning_scene_table_->clear(); 01741 int count = 0; 01742 for(map<string, PlanningSceneData>::iterator it = planning_scene_map_.begin(); it != planning_scene_map_.end(); it++) 01743 { 01744 count ++; 01745 } 01746 planning_scene_table_->setRowCount(count); 01747 planning_scene_table_->setColumnCount(4); 01748 QStringList labels; 01749 labels.append("Host"); 01750 labels.append("Name"); 01751 labels.append("Timestamp"); 01752 labels.append("Notes"); 01753 01754 ROS_INFO("Num Planning Scenes: %d", planning_scene_table_->rowCount()); 01755 01756 int r = 0; 01757 for(map<string, PlanningSceneData>::iterator it = planning_scene_map_.begin(); it != planning_scene_map_.end(); it++) 01758 { 01759 PlanningSceneData& data = it->second; 01760 01761 QTableWidgetItem* hostItem = new QTableWidgetItem(QString::fromStdString(data.getHostName())); 01762 hostItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01763 planning_scene_table_->setItem(r, 0, hostItem); 01764 01765 QTableWidgetItem* nameItem = new QTableWidgetItem(QString::fromStdString(data.getName())); 01766 nameItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01767 planning_scene_table_->setItem(r, 1, nameItem); 01768 01769 QDateTime time; 01770 time.setTime_t((unsigned int)(data.getTimeStamp().toSec())); 01771 stringstream timestampStream; 01772 timestampStream << time.toString().toStdString(); 01773 01774 QTableWidgetItem* timeItem = new QTableWidgetItem(QString::fromStdString(timestampStream.str())); 01775 timeItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01776 planning_scene_table_->setItem(r, 2, timeItem); 01777 01778 stringstream notesStream; 01779 01780 vector<ArmNavigationErrorCodes>& errorCodes = data.getErrorCodes(); 01781 01782 01783 if(errorCodes.size() == 0) 01784 { 01785 notesStream << "No Outcomes"; 01786 } 01787 else 01788 { 01789 notesStream << "Last Outcome: " << armNavigationErrorCodeToString(errorCodes.back()); 01790 } 01791 01792 QTableWidgetItem* notesItem = new QTableWidgetItem(QString::fromStdString(notesStream.str())); 01793 notesItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); 01794 planning_scene_table_->setItem(r, 3, notesItem); 01795 01796 if(errorCodes.size() != 0) 01797 { 01798 if(errorCodes.back().val != ArmNavigationErrorCodes::SUCCESS) 01799 { 01800 notesItem->setTextColor(QColor(180, 0, 0)); 01801 } 01802 } 01803 01804 r++; 01805 } 01806 01807 planning_scene_table_->sortByColumn(1, Qt::AscendingOrder); 01808 connect(planning_scene_table_->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(planningSceneTableHeaderClicked(int))); 01809 planning_scene_table_->horizontalHeader()->resizeSections(QHeaderView::Stretch); 01810 planning_scene_table_->setHorizontalHeaderLabels(labels); 01811 planning_scene_table_->setMinimumWidth(1000); 01812 01813 emit allScenesLoaded(); 01814 } 01815 01816 void WarehouseViewer::refreshPlanningSceneDialog() 01817 { 01818 planning_scene_table_->horizontalHeader()->resizeSections(QHeaderView::Stretch); 01819 } 01820 01821 void WarehouseViewer::planningSceneTableHeaderClicked(int col) { 01822 planning_scene_table_->sortByColumn(col); 01823 } 01824 01825 void WarehouseViewer::motionPlanJointControlsActiveButtonClicked(bool checked) 01826 { 01827 QObject* sender = QObject::sender(); 01828 QCheckBox* box = dynamic_cast<QCheckBox*>(sender); 01829 01830 if(box == NULL) 01831 { 01832 return; 01833 } 01834 01835 std::string ID = box->toolTip().toStdString(); 01836 01837 if(motion_plan_map_.find(ID) == motion_plan_map_.end()) 01838 { 01839 return; 01840 } 01841 01842 MotionPlanRequestData& data = motion_plan_map_[ID]; 01843 data.setJointControlsVisible(checked, this); 01844 interactive_marker_server_->applyChanges(); 01845 } 01846 01847 void WarehouseViewer::createNewObjectPressed() 01848 { 01849 collision_object_name_->setText(generateNewCollisionObjectId().c_str()); 01850 new_object_dialog_->show(); 01851 } 01852 01853 void WarehouseViewer::createNewObjectDialog() 01854 { 01855 new_object_dialog_ = new QDialog(this); 01856 QVBoxLayout* layout = new QVBoxLayout(new_object_dialog_); 01857 QGroupBox* panel = new QGroupBox(new_object_dialog_); 01858 panel->setTitle("New Collision Object"); 01859 01860 QVBoxLayout* panelLayout = new QVBoxLayout(panel); 01861 01862 collision_object_name_ = new QLineEdit(new_object_dialog_); 01863 panelLayout->addWidget(collision_object_name_); 01864 01865 collision_object_type_box_ = new QComboBox(new_object_dialog_); 01866 collision_object_type_box_->addItem("Box"); 01867 collision_object_type_box_->addItem("Cylinder"); 01868 collision_object_type_box_->addItem("Sphere"); 01869 collision_object_type_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01870 01871 panelLayout->addWidget(collision_object_type_box_); 01872 01873 QGroupBox* scaleBox = new QGroupBox(panel); 01874 scaleBox->setTitle("Scale (x,y,z) cm"); 01875 QHBoxLayout* scaleLayout = new QHBoxLayout(scaleBox); 01876 01877 collision_object_scale_x_box_ = new QSpinBox(scaleBox); 01878 collision_object_scale_y_box_ = new QSpinBox(scaleBox); 01879 collision_object_scale_z_box_ = new QSpinBox(scaleBox); 01880 collision_object_scale_x_box_->setRange(1, 10000); 01881 collision_object_scale_y_box_->setRange(1, 10000); 01882 collision_object_scale_z_box_->setRange(1, 10000); 01883 collision_object_scale_x_box_->setValue(10); 01884 collision_object_scale_y_box_->setValue(10); 01885 collision_object_scale_z_box_->setValue(10); 01886 collision_object_scale_x_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01887 collision_object_scale_y_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01888 collision_object_scale_z_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01889 01890 scaleLayout->addWidget(collision_object_scale_x_box_); 01891 scaleLayout->addWidget(collision_object_scale_y_box_); 01892 scaleLayout->addWidget(collision_object_scale_z_box_); 01893 01894 scaleBox->setLayout(scaleLayout); 01895 panelLayout->addWidget(scaleBox); 01896 01897 QGroupBox* posBox = new QGroupBox(panel); 01898 posBox->setTitle("Position (x,y,z) cm"); 01899 QHBoxLayout* posLayout = new QHBoxLayout(posBox); 01900 01901 01902 collision_object_pos_x_box_ = new QSpinBox(posBox); 01903 collision_object_pos_y_box_ = new QSpinBox(posBox); 01904 collision_object_pos_z_box_ = new QSpinBox(posBox); 01905 collision_object_pos_x_box_->setRange(-10000, 10000); 01906 collision_object_pos_y_box_->setRange(-10000, 10000); 01907 collision_object_pos_z_box_->setRange(-10000, 10000); 01908 collision_object_pos_x_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01909 collision_object_pos_y_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01910 collision_object_pos_z_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01911 01912 posLayout->addWidget(collision_object_pos_x_box_); 01913 posLayout->addWidget(collision_object_pos_y_box_); 01914 posLayout->addWidget(collision_object_pos_z_box_); 01915 01916 posBox->setLayout(posLayout); 01917 panelLayout->addWidget(posBox); 01918 01919 panel->setLayout(panelLayout); 01920 layout->addWidget(panel); 01921 01922 object_color_button_ = new QPushButton(new_object_dialog_); 01923 01924 std::stringstream colorStream; 01925 colorStream<< "Color: (" << (int)(last_collision_object_color_.r*255) <<" , "; 01926 colorStream << (int)(last_collision_object_color_.g*255) << " , "; 01927 colorStream << (int)(last_collision_object_color_.b*255) << ")"; 01928 01929 object_color_button_->setText(QString::fromStdString(colorStream.str())); 01930 object_color_button_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 01931 connect(object_color_button_, SIGNAL(clicked()), this, SLOT(objectColorButtonPressed())); 01932 01933 make_object_button_ = new QPushButton(new_object_dialog_); 01934 make_object_button_->setText("Create..."); 01935 make_object_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 01936 connect(make_object_button_, SIGNAL(clicked()), this, SLOT(createObjectConfirmedPressed())); 01937 01938 layout->addWidget(object_color_button_); 01939 layout->addWidget(make_object_button_); 01940 new_object_dialog_->setLayout(layout); 01941 01942 } 01943 01944 void WarehouseViewer::createNewMeshPressed() 01945 { 01946 mesh_object_name_->setText(generateNewCollisionObjectId().c_str()); 01947 new_mesh_dialog_->show(); 01948 } 01949 01950 void WarehouseViewer::meshFileSelected(const QString& filename) 01951 { 01952 mesh_filename_field_->setText(filename); 01953 } 01954 01955 void WarehouseViewer::createMeshConfirmedPressed() 01956 { 01957 geometry_msgs::Pose pose; 01958 pose.position.x = (float)mesh_object_pos_x_box_->value() / 100.0f; 01959 pose.position.y = (float)mesh_object_pos_y_box_->value() / 100.0f; 01960 pose.position.z = (float)mesh_object_pos_z_box_->value() / 100.0f; 01961 pose.orientation.x = 0; 01962 pose.orientation.y = 0; 01963 pose.orientation.z = 0; 01964 pose.orientation.w = 1; 01965 01966 btVector3 scale; 01967 scale.setX(mesh_object_scale_x_box_->value()); 01968 scale.setY(mesh_object_scale_y_box_->value()); 01969 scale.setZ(mesh_object_scale_z_box_->value()); 01970 01971 createMeshObject(mesh_object_name_->text().toStdString(), pose, "file://"+mesh_filename_field_->text().toStdString(), scale, last_mesh_object_color_); 01972 new_mesh_dialog_->hide(); 01973 } 01974 01975 void WarehouseViewer::createNewMeshDialog() 01976 { 01977 new_mesh_dialog_ = new QDialog(this); 01978 QVBoxLayout* layout = new QVBoxLayout(new_mesh_dialog_); 01979 QGroupBox* panel = new QGroupBox(new_mesh_dialog_); 01980 panel->setTitle("New Mesh Collision Object"); 01981 01982 QVBoxLayout* panelLayout = new QVBoxLayout(panel); 01983 mesh_object_name_ = new QLineEdit(this); 01984 panelLayout->addWidget(mesh_object_name_); 01985 01986 mesh_filename_field_ = new QLineEdit(this); 01987 mesh_filename_field_->setText("<mesh_filename>"); 01988 panelLayout->addWidget(mesh_filename_field_); 01989 01990 QPushButton* selectFileButton = new QPushButton(this); 01991 selectFileButton->setText("Select Mesh file ..."); 01992 01993 file_selector_ = new QFileDialog(this); 01994 file_selector_->setFileMode(QFileDialog::ExistingFile); 01995 file_selector_->setOption(QFileDialog::ReadOnly, true); 01996 QStringList filters; 01997 filters << "Mesh files (*.stl *.stla *.stlb *.dae *.ply)"; 01998 file_selector_->setNameFilters(filters); 01999 02000 connect(file_selector_, SIGNAL(fileSelected(const QString&)), this, SLOT(meshFileSelected(const QString&))); 02001 connect(selectFileButton, SIGNAL(clicked()), file_selector_, SLOT(open())); 02002 panelLayout->addWidget(selectFileButton); 02003 02004 QGroupBox* posBox = new QGroupBox(panel); 02005 posBox->setTitle("Position (x,y,z) cm"); 02006 QHBoxLayout* posLayout = new QHBoxLayout(posBox); 02007 02008 mesh_object_pos_x_box_ = new QSpinBox(posBox); 02009 mesh_object_pos_y_box_ = new QSpinBox(posBox); 02010 mesh_object_pos_z_box_ = new QSpinBox(posBox); 02011 mesh_object_pos_x_box_->setRange(-10000, 10000); 02012 mesh_object_pos_y_box_->setRange(-10000, 10000); 02013 mesh_object_pos_z_box_->setRange(-10000, 10000); 02014 mesh_object_pos_x_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02015 mesh_object_pos_y_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02016 mesh_object_pos_z_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02017 02018 posLayout->addWidget(mesh_object_pos_x_box_); 02019 posLayout->addWidget(mesh_object_pos_y_box_); 02020 posLayout->addWidget(mesh_object_pos_z_box_); 02021 posBox->setLayout(posLayout); 02022 02023 QGroupBox* scaleBox = new QGroupBox(panel); 02024 scaleBox->setTitle("Scale (x,y,z)"); 02025 QHBoxLayout* scaleLayout = new QHBoxLayout(scaleBox); 02026 02027 mesh_object_scale_x_box_ = new QDoubleSpinBox(scaleBox); 02028 mesh_object_scale_y_box_ = new QDoubleSpinBox(scaleBox); 02029 mesh_object_scale_z_box_ = new QDoubleSpinBox(scaleBox); 02030 mesh_object_scale_x_box_->setDecimals(4); 02031 mesh_object_scale_x_box_->setSingleStep(.0001); 02032 mesh_object_scale_y_box_->setDecimals(4); 02033 mesh_object_scale_y_box_->setSingleStep(.0001); 02034 mesh_object_scale_z_box_->setDecimals(4); 02035 mesh_object_scale_z_box_->setSingleStep(.0001); 02036 mesh_object_scale_x_box_->setRange(0, 10.0); 02037 mesh_object_scale_y_box_->setRange(0, 10.0); 02038 mesh_object_scale_z_box_->setRange(0, 10.0); 02039 mesh_object_scale_x_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02040 mesh_object_scale_y_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02041 mesh_object_scale_z_box_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02042 mesh_object_scale_x_box_->setValue(1.0); 02043 mesh_object_scale_y_box_->setValue(1.0); 02044 mesh_object_scale_z_box_->setValue(1.0); 02045 02046 scaleLayout->addWidget(mesh_object_scale_x_box_); 02047 scaleLayout->addWidget(mesh_object_scale_y_box_); 02048 scaleLayout->addWidget(mesh_object_scale_z_box_); 02049 02050 scaleBox->setLayout(scaleLayout); 02051 02052 panelLayout->addWidget(posBox); 02053 panelLayout->addWidget(scaleBox); 02054 02055 panel->setLayout(panelLayout); 02056 layout->addWidget(panel); 02057 02058 mesh_color_button_ = new QPushButton(new_mesh_dialog_); 02059 02060 std::stringstream colorStream; 02061 colorStream<< "Color: (" << (int)(last_mesh_object_color_.r*255) <<" , "; 02062 colorStream << (int)(last_mesh_object_color_.g*255) << " , "; 02063 colorStream << (int)(last_mesh_object_color_.b*255) << ")"; 02064 02065 mesh_color_button_->setText(QString::fromStdString(colorStream.str())); 02066 mesh_color_button_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 02067 connect(mesh_color_button_, SIGNAL(clicked()), this, SLOT(meshColorButtonPressed())); 02068 02069 make_mesh_button_ = new QPushButton(new_mesh_dialog_); 02070 make_mesh_button_->setText("Create..."); 02071 make_mesh_button_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02072 connect(make_mesh_button_, SIGNAL(clicked()), this, SLOT(createMeshConfirmedPressed())); 02073 02074 layout->addWidget(mesh_color_button_); 02075 layout->addWidget(make_mesh_button_); 02076 new_mesh_dialog_->setLayout(layout); 02077 02078 } 02079 02080 void WarehouseViewer::meshColorButtonPressed() 02081 { 02082 02083 QColor selected = QColorDialog::getColor(QColor(last_mesh_object_color_.r*255, last_mesh_object_color_.g*255, last_mesh_object_color_.b*255), new_object_dialog_); 02084 02085 if(selected.isValid()) 02086 { 02087 last_mesh_object_color_.r = selected.redF(); 02088 last_mesh_object_color_.g = selected.greenF(); 02089 last_mesh_object_color_.b = selected.blueF(); 02090 last_mesh_object_color_.a = 1.0; 02091 02092 std::stringstream colorStream; 02093 colorStream<< "Color: (" << (int)(last_mesh_object_color_.r*255) <<" , "; 02094 colorStream << (int)(last_mesh_object_color_.g*255) << " , "; 02095 colorStream << (int)(last_mesh_object_color_.b*255) << ")"; 02096 02097 mesh_color_button_->setText(QString::fromStdString(colorStream.str())); 02098 } 02099 } 02100 02101 void WarehouseViewer::objectColorButtonPressed() 02102 { 02103 02104 QColor selected = QColorDialog::getColor(QColor(last_collision_object_color_.r*255, last_collision_object_color_.g*255, last_collision_object_color_.b*255), new_object_dialog_); 02105 02106 if(selected.isValid()) 02107 { 02108 last_collision_object_color_.r = selected.redF(); 02109 last_collision_object_color_.g = selected.greenF(); 02110 last_collision_object_color_.b = selected.blueF(); 02111 last_collision_object_color_.a = 1.0; 02112 02113 std::stringstream colorStream; 02114 colorStream<< "Color: (" << (int)(last_collision_object_color_.r*255) <<" , "; 02115 colorStream << (int)(last_collision_object_color_.g*255) << " , "; 02116 colorStream << (int)(last_collision_object_color_.b*255) << ")"; 02117 02118 object_color_button_->setText(QString::fromStdString(colorStream.str())); 02119 } 02120 } 02121 02122 void WarehouseViewer::createObjectConfirmedPressed() 02123 { 02124 geometry_msgs::Pose pose; 02125 pose.position.x = (float)collision_object_pos_x_box_->value() / 100.0f; 02126 pose.position.y = (float)collision_object_pos_y_box_->value() / 100.0f; 02127 pose.position.z = (float)collision_object_pos_z_box_->value() / 100.0f; 02128 pose.orientation.x = 0; 02129 pose.orientation.y = 0; 02130 pose.orientation.z = 0; 02131 pose.orientation.w = 1; 02132 02133 std::string name = collision_object_type_box_->currentText().toStdString(); 02134 PlanningSceneEditor::GeneratedShape shape; 02135 if(name == "Box") 02136 { 02137 shape = PlanningSceneEditor::Box; 02138 } 02139 if(name == "Cylinder") 02140 { 02141 shape = PlanningSceneEditor::Cylinder; 02142 } 02143 if(name == "Sphere") 02144 { 02145 shape = PlanningSceneEditor::Sphere; 02146 } 02147 02148 02149 createCollisionObject(collision_object_name_->text().toStdString(), 02150 pose, shape, (float)collision_object_scale_x_box_->value() / 100.0f, 02151 (float)collision_object_scale_y_box_->value() / 100.0f, 02152 (float)collision_object_scale_z_box_->value() / 100.0f, last_collision_object_color_); 02153 new_object_dialog_->hide(); 02154 } 02155 02156 void WarehouseViewer::createRequestDialog() 02157 { 02158 new_request_dialog_ = new QDialog(this); 02159 QVBoxLayout* layout = new QVBoxLayout(new_request_dialog_); 02160 QGroupBox* box = new QGroupBox(new_request_dialog_); 02161 QVBoxLayout* boxLayout = new QVBoxLayout(box); 02162 box->setTitle("New Motion Plan Request"); 02163 QLabel* boxLabel = new QLabel(box); 02164 boxLabel->setText("Planning Group:"); 02165 request_group_name_box_ = new QComboBox(box); 02166 02167 if(params_.right_arm_group_ != "none") 02168 { 02169 request_group_name_box_->addItem(QString::fromStdString(params_.right_arm_group_)); 02170 } 02171 02172 if(params_.left_arm_group_ != "none") 02173 { 02174 request_group_name_box_->addItem(QString::fromStdString(params_.left_arm_group_)); 02175 } 02176 02177 create_request_from_robot_box_ = new QCheckBox(box); 02178 create_request_from_robot_box_->setChecked(params_.use_robot_data_); 02179 create_request_from_robot_box_->setText("Start From Current Robot State"); 02180 02181 boxLayout->addWidget(boxLabel); 02182 boxLayout->addWidget(request_group_name_box_); 02183 boxLayout->addWidget(create_request_from_robot_box_); 02184 02185 QPushButton* createRequestButton = new QPushButton(box); 02186 createRequestButton->setText("Create ..."); 02187 createRequestButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 02188 boxLayout->addWidget(createRequestButton); 02189 02190 connect(createRequestButton, SIGNAL(clicked()), this, SLOT(createRequestPressed())); 02191 layout->addWidget(box); 02192 new_request_dialog_->setLayout(layout); 02193 } 02194 02195 void WarehouseViewer::createRequestPressed() 02196 { 02197 std::string group_name = request_group_name_box_->currentText().toStdString(); 02198 std::string end_effector_name = ""; 02199 02200 if(group_name == params_.right_arm_group_) 02201 { 02202 end_effector_name = params_.right_ik_link_; 02203 } 02204 else if(group_name == params_.left_arm_group_) 02205 { 02206 end_effector_name = params_.left_ik_link_; 02207 } 02208 else 02209 { 02210 return; 02211 } 02212 createNewMotionPlanRequest(group_name, end_effector_name); 02213 createMotionPlanTable(); 02214 new_request_dialog_->close(); 02215 } 02216 02217 void WarehouseViewer::trajectoryRenderTypeChanged(const QString& type) 02218 { 02219 QObject* sender = QObject::sender(); 02220 QComboBox* box = dynamic_cast<QComboBox*>(sender); 02221 std::string ID = box->toolTip().toStdString(); 02222 02223 if(!hasTrajectory(selected_motion_plan_name_, 02224 ID)) { 02225 ROS_WARN_STREAM("Changing render type when we don't have trajectory"); 02226 return; 02227 } 02228 02229 TrajectoryData& data = trajectory_map_[selected_motion_plan_name_][ID]; 02230 02231 if(type == "Visual Mesh") 02232 { 02233 data.setRenderType(VisualMesh); 02234 } 02235 else if(type == "Collision Mesh") 02236 { 02237 data.setRenderType(CollisionMesh); 02238 } 02239 else 02240 { 02241 data.setRenderType(PaddingMesh); 02242 } 02243 } 02244 02245 void WarehouseViewer::motionPlanRenderTypeChanged(const QString& type) 02246 { 02247 QObject* sender = QObject::sender(); 02248 QComboBox* box = dynamic_cast<QComboBox*>(sender); 02249 std::string ID = box->toolTip().toStdString(); 02250 02251 if(motion_plan_map_.find(ID) == motion_plan_map_.end()) 02252 { 02253 return; 02254 } 02255 02256 MotionPlanRequestData& data = motion_plan_map_[ID]; 02257 02258 if(type == "Visual Mesh") 02259 { 02260 data.setRenderType(VisualMesh); 02261 } 02262 else if(type == "Collision Mesh") 02263 { 02264 data.setRenderType(CollisionMesh); 02265 } 02266 else 02267 { 02268 data.setRenderType(PaddingMesh); 02269 } 02270 } 02271 02272 void WarehouseViewer::planCallback(arm_navigation_msgs::ArmNavigationErrorCodes& errorCode) 02273 { 02274 if(errorCode.val != ArmNavigationErrorCodes::SUCCESS) 02275 { 02276 emit plannerFailure(errorCode.val); 02277 } else { 02278 selectTrajectory(selected_trajectory_name_); 02279 } 02280 } 02281 02282 02283 void WarehouseViewer::filterCallback(arm_navigation_msgs::ArmNavigationErrorCodes& errorCode) 02284 { 02285 if(errorCode.val != ArmNavigationErrorCodes::SUCCESS) 02286 { 02287 emit filterFailure(errorCode.val); 02288 } else { 02289 selectTrajectory(selected_trajectory_name_); 02290 } 02291 } 02292 02293 void WarehouseViewer::attachObject(const std::string& name) 02294 { 02295 createAttachObjectDialog(name); 02296 int res = attach_object_dialog_->exec(); 02297 if(res == QDialog::Accepted) { 02298 std::vector<std::string> touch_links; 02299 for(int i = 0; i < added_touch_links_->count(); i++) { 02300 touch_links.push_back(added_touch_links_->item(i)->text().toStdString()); 02301 02302 } 02303 attachCollisionObject(name, attach_link_box_->currentText().toStdString(), touch_links); 02304 changeToAttached(name); 02305 } 02306 delete attach_object_dialog_; 02307 } 02308 02309 void WarehouseViewer::createAttachObjectDialog(const std::string& name) 02310 { 02311 if(current_planning_scene_name_ == "") { 02312 return; 02313 } 02314 02315 arm_navigation_msgs::PlanningScene planning_scene = planning_scene_map_[current_planning_scene_name_].getPlanningScene(); 02316 02317 std::stringstream ss; 02318 ss << "Attach object " << name; 02319 02320 attach_object_dialog_ = new QDialog(this); 02321 attach_object_dialog_->setWindowTitle(ss.str().c_str()); 02322 02323 QVBoxLayout* layout = new QVBoxLayout(attach_object_dialog_); 02324 02325 QGroupBox* panel = new QGroupBox(attach_object_dialog_); 02326 panel->setTitle("Link for attaching"); 02327 02328 QVBoxLayout* panel_layout = new QVBoxLayout(panel); 02329 attach_link_box_= new QComboBox(attach_object_dialog_); 02330 02331 std::vector<std::string> link_names; 02332 cm_->getKinematicModel()->getLinkModelNames(link_names); 02333 for(unsigned int i = 0; i < link_names.size(); i++) { 02334 attach_link_box_->addItem(link_names[i].c_str()); 02335 } 02336 panel_layout->addWidget(attach_link_box_); 02337 panel->setLayout(panel_layout); 02338 layout->addWidget(panel); 02339 02340 QGroupBox* grid_panel = new QGroupBox(attach_object_dialog_); 02341 QGridLayout* grid = new QGridLayout(grid_panel); 02342 02343 QLabel* all_label = new QLabel(attach_object_dialog_); 02344 all_label->setText("Links and groups"); 02345 02346 QLabel* touch_links = new QLabel(attach_object_dialog_); 02347 touch_links->setText("Touch links"); 02348 02349 grid->addWidget(all_label, 0, 0); 02350 grid->addWidget(touch_links, 0, 2); 02351 02352 QPushButton* add_button = new QPushButton(attach_object_dialog_); 02353 add_button->setText("Add ->"); 02354 02355 connect(add_button, SIGNAL(clicked()), this, SLOT(addTouchLinkClicked())); 02356 02357 QPushButton* remove_button = new QPushButton(attach_object_dialog_); 02358 remove_button->setText("Remove"); 02359 02360 connect(remove_button, SIGNAL(clicked()), this, SLOT(removeTouchLinkClicked())); 02361 02362 grid->addWidget(add_button, 1, 1, Qt::AlignTop); 02363 grid->addWidget(remove_button, 1, 1, Qt::AlignBottom); 02364 02365 possible_touch_links_ = new QListWidget(attach_object_dialog_); 02366 possible_touch_links_->setSelectionMode(QAbstractItemView::ExtendedSelection); 02367 for(unsigned int i = 0; i < link_names.size(); i++) { 02368 possible_touch_links_->addItem(link_names[i].c_str()); 02369 } 02370 possible_touch_links_->addItem("------Groups---------"); 02371 std::vector<std::string> group_names; 02372 cm_->getKinematicModel()->getModelGroupNames(group_names); 02373 for(unsigned int i = 0; i < group_names.size(); i++) { 02374 possible_touch_links_->addItem(group_names[i].c_str()); 02375 } 02376 added_touch_links_ = new QListWidget(attach_object_dialog_); 02377 added_touch_links_->setSelectionMode(QAbstractItemView::ExtendedSelection); 02378 02379 grid->addWidget(possible_touch_links_, 1, 0); 02380 grid->addWidget(added_touch_links_, 1, 2); 02381 02382 layout->addWidget(grid_panel); 02383 02384 QDialogButtonBox* qdb = new QDialogButtonBox(); 02385 QPushButton* cancel_button = new QPushButton("Cancel"); 02386 QPushButton* attach_button = new QPushButton("Attach"); 02387 qdb->addButton(cancel_button, QDialogButtonBox::RejectRole); 02388 qdb->addButton(attach_button, QDialogButtonBox::AcceptRole); 02389 connect(qdb, SIGNAL(accepted()), attach_object_dialog_, SLOT(accept())); 02390 connect(qdb, SIGNAL(rejected()), attach_object_dialog_, SLOT(reject())); 02391 02392 layout->addWidget(qdb, Qt::AlignRight); 02393 02394 attach_object_dialog_->setLayout(layout); 02395 } 02396 02397 void WarehouseViewer::addTouchLinkClicked() 02398 { 02399 QList<QListWidgetItem *> l = possible_touch_links_->selectedItems(); 02400 02401 for(int i = 0; i < l.size(); i++) { 02402 bool found = false; 02403 for(int j = 0; j < added_touch_links_->count(); j++) { 02404 if(l[i]->text() == added_touch_links_->item(j)->text()) { 02405 found = true; 02406 break; 02407 } 02408 } 02409 if(!found && l[i]->text().toStdString() != std::string("------Groups---------")) { 02410 added_touch_links_->addItem(l[i]->text()); 02411 } 02412 } 02413 } 02414 02415 void WarehouseViewer::removeTouchLinkClicked() 02416 { 02417 qDeleteAll(added_touch_links_->selectedItems()); 02418 } 02419 02420 void WarehouseViewer::editRobotStatePressed() 02421 { 02422 createRobotStateEditor(); 02423 edit_robot_state_dialog_->exec(); 02424 delete edit_robot_state_dialog_; 02425 } 02426 02427 void WarehouseViewer::createRobotStateEditor() { 02428 02429 edit_robot_state_dialog_ = new QDialog(this); 02430 edit_robot_state_dialog_->setWindowTitle("Edit robot state"); 02431 02432 QVBoxLayout* layout = new QVBoxLayout(edit_robot_state_dialog_); 02433 02434 QGroupBox* panel = new QGroupBox(edit_robot_state_dialog_); 02435 panel->setTitle("Joint state to edit"); 02436 02437 QVBoxLayout* panel_layout = new QVBoxLayout(panel); 02438 edit_joint_box_= new QComboBox(edit_robot_state_dialog_); 02439 02440 const std::vector<planning_models::KinematicModel::JointModel*>& joint_models = cm_->getKinematicModel()->getJointModels(); 02441 for(unsigned int i = 0; i < joint_models.size(); i++) { 02442 if(joint_models[i]->getComputatationOrderMapIndex().size() == 1) { 02443 edit_joint_box_->addItem(joint_models[i]->getName().c_str()); 02444 } 02445 } 02446 02447 QGridLayout* slider_layout = new QGridLayout(panel); 02448 02449 QLabel* lower_label = new QLabel(edit_robot_state_dialog_); 02450 lower_label->setText("Lower bound"); 02451 02452 QLabel* upper_label = new QLabel(edit_robot_state_dialog_); 02453 upper_label->setText("Upper bound"); 02454 02455 QLabel* current_label = new QLabel(edit_robot_state_dialog_); 02456 current_label->setText("Current value"); 02457 02458 lower_bound_edit_window_ = new QLineEdit(edit_robot_state_dialog_); 02459 upper_bound_edit_window_ = new QLineEdit(edit_robot_state_dialog_); 02460 current_value_window_ = new QLineEdit(edit_robot_state_dialog_); 02461 02462 lower_bound_edit_window_->setReadOnly(true); 02463 upper_bound_edit_window_->setReadOnly(true); 02464 lower_bound_edit_window_->setMinimumWidth(125); 02465 lower_bound_edit_window_->setMaximumWidth(125); 02466 upper_bound_edit_window_->setMinimumWidth(125); 02467 upper_bound_edit_window_->setMaximumWidth(125); 02468 02469 joint_state_slider_ = new QSlider(Qt::Horizontal, edit_robot_state_dialog_); 02470 joint_state_slider_->setMinimum(0); 02471 joint_state_slider_->setMaximum(0); 02472 02473 slider_layout->addWidget(lower_label, 0, 0); 02474 slider_layout->addWidget(current_label, 0, 1); 02475 slider_layout->addWidget(upper_label, 0, 2); 02476 02477 slider_layout->addWidget(lower_bound_edit_window_, 1, 0); 02478 slider_layout->addWidget(joint_state_slider_, 1, 1); 02479 slider_layout->addWidget(upper_bound_edit_window_, 1, 2); 02480 02481 slider_layout->addWidget(current_value_window_, 2, 1); 02482 02483 slider_layout->setColumnStretch(1, 100); 02484 02485 panel_layout->addWidget(edit_joint_box_); 02486 panel_layout->addLayout(slider_layout); 02487 02488 panel->setLayout(panel_layout); 02489 layout->addWidget(panel); 02490 02491 edit_robot_state_dialog_->setLayout(layout); 02492 02493 //getting reasonable stuff in there 02494 editJointBoxChanged(edit_joint_box_->currentText()); 02495 02496 connect(edit_joint_box_, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(editJointBoxChanged(const QString&))); 02497 connect(joint_state_slider_, SIGNAL(valueChanged(int)), this, SLOT(jointStateSliderChanged(int))); 02498 } 02499 02500 void WarehouseViewer::editJointBoxChanged(const QString& joint) 02501 { 02502 02503 std::map<std::string, double> current_joint_state_values; 02504 robot_state_->getKinematicStateValues(current_joint_state_values); 02505 02506 double current_value = current_joint_state_values[joint.toStdString()]; 02507 02508 const planning_models::KinematicModel::JointModel* jm = cm_->getKinematicModel()->getJointModel(joint.toStdString()); 02509 02510 std::pair<double, double> bounds; 02511 jm->getVariableBounds(jm->getName(), bounds); 02512 02513 std::stringstream lb; 02514 lb << bounds.first; 02515 std::stringstream ub; 02516 ub << bounds.second; 02517 02518 std::stringstream cur; 02519 cur << current_value; 02520 02521 lower_bound_edit_window_->setText(lb.str().c_str()); 02522 upper_bound_edit_window_->setText(ub.str().c_str()); 02523 current_value_window_->setText(cur.str().c_str()); 02524 02525 joint_state_slider_->setMinimum(bounds.first*1000); 02526 joint_state_slider_->setMaximum(bounds.second*1000); 02527 joint_state_slider_->setValue(current_value*1000); 02528 } 02529 02530 void WarehouseViewer::jointStateSliderChanged(int nv) 02531 { 02532 std::map<std::string, double> current_joint_state_values; 02533 robot_state_->getKinematicStateValues(current_joint_state_values); 02534 02535 current_joint_state_values[edit_joint_box_->currentText().toStdString()] = nv/1000.0; 02536 02537 std::stringstream cur; 02538 cur << nv/1000.0; 02539 current_value_window_->setText(cur.str().c_str()); 02540 02541 robot_state_->setKinematicState(current_joint_state_values); 02542 02543 planning_environment::convertKinematicStateToRobotState(*robot_state_, 02544 ros::Time::now(), 02545 cm_->getWorldFrameId(), 02546 planning_scene_map_[current_planning_scene_name_].getPlanningScene().robot_state); 02547 sendPlanningScene(planning_scene_map_[current_planning_scene_name_]); 02548 } 02549 02550 void WarehouseViewer::popupPlannerFailure(int value) 02551 { 02552 ArmNavigationErrorCodes errorCode; 02553 errorCode.val = value; 02554 std::string failure = "Planning Failed: " + armNavigationErrorCodeToString(errorCode); 02555 QMessageBox msg(QMessageBox::Critical, "Planning Failed!", QString::fromStdString(failure)); 02556 msg.addButton("Ok", QMessageBox::AcceptRole); 02557 msg.exec(); 02558 } 02559 02560 void WarehouseViewer::popupFilterFailure(int value) 02561 { 02562 ArmNavigationErrorCodes errorCode; 02563 errorCode.val = value; 02564 std::string failure = "Filter Failed: " + armNavigationErrorCodeToString(errorCode); 02565 QMessageBox msg(QMessageBox::Critical, "Filter Failed!", QString::fromStdString(failure)); 02566 msg.addButton("Ok", QMessageBox::AcceptRole); 02567 msg.exec(); 02568 } 02569 02570 void marker_function() 02571 { 02572 unsigned int counter = 0; 02573 while(ros::ok()) 02574 { 02575 if(inited) 02576 { 02577 if(counter % CONTROL_SPEED == 0) 02578 { 02579 counter = 1; 02580 psv->sendMarkers(); 02581 } 02582 else 02583 { 02584 counter++; 02585 } 02586 02587 if(psv->quit_threads_) 02588 { 02589 break; 02590 } 02591 } 02592 usleep(5000); 02593 } 02594 02595 } 02596 02597 void spin_function() 02598 { 02599 ros::WallRate r(100.0); 02600 while(ros::ok() && !inited) 02601 { 02602 r.sleep(); 02603 ros::spinOnce(); 02604 } 02605 while(ros::ok() && !psv->quit_threads_) 02606 { 02607 r.sleep(); 02608 ros::spinOnce(); 02609 } 02610 } 02611 02612 void quit(int sig) 02613 { 02614 if(psv != NULL) 02615 { 02616 delete psv; 02617 } 02618 } 02619 02620 int main(int argc, char** argv) 02621 { 02622 ros::init(argc, argv, "planning_scene_warehouse_viewer", ros::init_options::NoSigintHandler); 02623 02624 boost::thread spin_thread(boost::bind(&spin_function)); 02625 boost::thread marker_thread(boost::bind(&marker_function)); 02626 02627 QApplication* app = new QApplication(argc, argv); 02628 planning_scene_utils::PlanningSceneParameters params; 02629 param<string>("set_planning_scene_diff_name", params.set_planning_scene_diff_name_, SET_PLANNING_SCENE_DIFF_NAME); 02630 param<string>("left_ik_name", params.left_ik_name_, LEFT_IK_NAME); 02631 param<string>("left_interpolate_service_name", params.left_interpolate_service_name_, LEFT_INTERPOLATE_SERVICE_NAME); 02632 param<string>("non_coll_left_ik_name", params.non_coll_left_ik_name_, NON_COLL_LEFT_IK_NAME); 02633 param<string>("non_coll_right_ik_name", params.non_coll_right_ik_name_, NON_COLL_RIGHT_IK_NAME); 02634 param<string>("planner_service_name", params.planner_service_name_, PLANNER_SERVICE_NAME); 02635 param<string>("proximity_space_planner_name", params.proximity_space_planner_name_, PROXIMITY_SPACE_PLANNER_NAME); 02636 param<string>("proximity_space_service_name", params.proximity_space_service_name_, PROXIMITY_SPACE_SERVICE_NAME); 02637 param<string>("proximity_space_validity_name", params.proximity_space_validity_name_, PROXIMITY_SPACE_VALIDITY_NAME); 02638 param<string>("right_ik_name", params.right_ik_name_, RIGHT_IK_NAME); 02639 param<string>("right_interpolate_service_name", params.right_interpolate_service_name_, RIGHT_INTERPOLATE_SERVICE_NAME); 02640 param<string>("trajectory_filter_service_name", params.trajectory_filter_service_name_, TRAJECTORY_FILTER_SERVICE_NAME); 02641 param<string>("vis_topic_name", params.vis_topic_name_ , VIS_TOPIC_NAME); 02642 param<string>("right_ik_link", params.right_ik_link_ , RIGHT_IK_LINK); 02643 param<string>("left_ik_link", params.left_ik_link_ , LEFT_IK_LINK); 02644 param<string>("right_arm_group", params.right_arm_group_ , RIGHT_ARM_GROUP); 02645 param<string>("left_arm_group", params.left_arm_group_ , LEFT_ARM_GROUP); 02646 param<string>("right_redundancy", params.right_redundancy_ , RIGHT_ARM_REDUNDANCY); 02647 param<string>("left_redundancy", params.left_redundancy_ , LEFT_ARM_REDUNDANCY); 02648 param<string>("execute_left_trajectory", params.execute_left_trajectory_ , EXECUTE_LEFT_TRAJECTORY); 02649 param<string>("execute_right_trajectory", params.execute_right_trajectory_ , EXECUTE_RIGHT_TRAJECTORY); 02650 param<string>("list_controllers_service", params.list_controllers_service_, LIST_CONTROLLERS_SERVICE); 02651 param<string>("load_controllers_service", params.load_controllers_service_, LOAD_CONTROLLERS_SERVICE); 02652 param<string>("unload_controllers_service", params.unload_controllers_service_, UNLOAD_CONTROLLERS_SERVICE); 02653 param<string>("switch_controllers_service", params.switch_controllers_service_, SWITCH_CONTROLLERS_SERVICE); 02654 param<string>("gazebo_robot_model", params.gazebo_model_name_, GAZEBO_ROBOT_MODEL); 02655 param<string>("robot_description_param", params.robot_description_param_, ROBOT_DESCRIPTION_PARAM); 02656 param<bool>("use_robot_data", params.use_robot_data_, false); 02657 params.sync_robot_state_with_gazebo_ = false; 02658 02659 ParameterDialog* dialog = new ParameterDialog(params); 02660 dialog->exec(); 02661 dialog->updateParams(); 02662 02663 QImage image; 02664 if(chdir(ros::package::getPath("move_arm_warehouse").c_str()) != 0) 02665 { 02666 ROS_ERROR("FAILED TO CHANGE PACKAGE TO %s", ros::package::getPath("move_arm_warehouse").c_str()); 02667 } 02668 if(!image.load("./res/splash.png")) 02669 { 02670 ROS_ERROR("FAILED TO LOAD ./res/splash.png"); 02671 } 02672 02673 QSplashScreen screen(QPixmap::fromImage(image)); 02674 screen.show(); 02675 app->processEvents(); 02676 psv = new WarehouseViewer(NULL, dialog->params_); 02677 app->setActiveWindow(psv); 02678 psv->show(); 02679 screen.close(); 02680 inited = true; 02681 02682 int ret = app->exec(); 02683 psv->quit_threads_ = true; 02684 spin_thread.join(); 02685 marker_thread.join(); 02686 return ret; 02687 02688 }