00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <main_window.h>
00038 #include <job_processing.h>
00039 #include <benchmark_processing_thread.h>
00040
00041 #include <moveit/kinematic_constraints/utils.h>
00042 #include <moveit/robot_state/conversions.h>
00043 #include <moveit/warehouse/constraints_storage.h>
00044 #include <moveit/warehouse/state_storage.h>
00045 #include <moveit/benchmarks/benchmark_execution.h>
00046 #include <moveit/planning_interface/planning_interface.h>
00047
00048 #include <pluginlib/class_loader.h>
00049
00050 #include <rviz/display_context.h>
00051 #include <rviz/window_manager_interface.h>
00052
00053 #include <eigen_conversions/eigen_msg.h>
00054
00055 #include <QMessageBox>
00056 #include <QInputDialog>
00057 #include <QFileDialog>
00058 #include <QProgressDialog>
00059
00060 #include <boost/math/constants/constants.hpp>
00061
00062 namespace benchmark_tool
00063 {
00064
00065 void MainWindow::createGoalAtPose(const std::string &name, const Eigen::Affine3d &pose)
00066 {
00067 goals_initial_pose_.insert(std::pair<std::string, Eigen::Affine3d>(name, pose));
00068
00069 geometry_msgs::Pose marker_pose;
00070 tf::poseEigenToMsg(pose * goal_offset_, marker_pose);
00071 static const float marker_scale = 0.15;
00072
00073 GripperMarkerPtr goal_pose(new GripperMarker(scene_display_->getPlanningSceneRO()->getCurrentState(), scene_display_->getSceneNode(), visualization_manager_, name, scene_display_->getRobotModel()->getModelFrame(),
00074 robot_interaction_->getActiveEndEffectors()[0], marker_pose, marker_scale, GripperMarker::NOT_TESTED));
00075 goal_poses_.insert(GoalPosePair(name, goal_pose));
00076
00077
00078 goal_pose->connect(this, SLOT( goalPoseFeedback(visualization_msgs::InteractiveMarkerFeedback &) ));
00079
00080
00081 if (constraints_storage_)
00082 {
00083 saveGoalsToDB();
00084 }
00085 }
00086
00087 void MainWindow::saveGoalsToDB()
00088 {
00089 if (constraints_storage_)
00090 {
00091
00092 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00093 {
00094 moveit_msgs::Constraints constraints;
00095 constraints.name = it->first;
00096
00097 shape_msgs::SolidPrimitive sp;
00098 sp.type = sp.BOX;
00099 sp.dimensions.resize(3, std::numeric_limits<float>::epsilon() * 10.0);
00100
00101 moveit_msgs::PositionConstraint pc;
00102 pc.header.frame_id = scene_display_->getRobotModel()->getModelFrame();
00103 pc.link_name = robot_interaction_->getActiveEndEffectors()[0].parent_link;
00104 pc.constraint_region.primitives.push_back(sp);
00105 geometry_msgs::Pose posemsg;
00106 it->second->getPosition(posemsg.position);
00107 posemsg.orientation.x = 0.0;
00108 posemsg.orientation.y = 0.0;
00109 posemsg.orientation.z = 0.0;
00110 posemsg.orientation.w = 1.0;
00111 pc.constraint_region.primitive_poses.push_back(posemsg);
00112 pc.weight = 1.0;
00113 constraints.position_constraints.push_back(pc);
00114
00115 moveit_msgs::OrientationConstraint oc;
00116 oc.header.frame_id = scene_display_->getRobotModel()->getModelFrame();
00117 oc.link_name = robot_interaction_->getActiveEndEffectors()[0].parent_link;
00118 it->second->getOrientation(oc.orientation);
00119 oc.absolute_x_axis_tolerance = oc.absolute_y_axis_tolerance =
00120 oc.absolute_z_axis_tolerance = std::numeric_limits<float>::epsilon() * 10.0;
00121 oc.weight = 1.0;
00122 constraints.orientation_constraints.push_back(oc);
00123
00124 try
00125 {
00126 constraints_storage_->addConstraints(constraints);
00127 }
00128 catch (std::runtime_error &ex)
00129 {
00130 ROS_ERROR("Cannot save constraint: %s", ex.what());
00131 }
00132 }
00133 }
00134 else
00135 {
00136 QMessageBox::warning(this, "Warning", "Not connected to a database.");
00137 }
00138 }
00139
00140 void MainWindow::createGoalPoseButtonClicked(void)
00141 {
00142 std::stringstream ss;
00143
00144 {
00145 const planning_scene_monitor::LockedPlanningSceneRO &ps = scene_display_->getPlanningSceneRO();
00146 if ( ! ps || robot_interaction_->getActiveEndEffectors().empty() )
00147 {
00148 if ( ! ps ) ROS_ERROR("Not planning scene");
00149 if ( robot_interaction_->getActiveEndEffectors().empty() ) ROS_ERROR("No end effector");
00150 return;
00151 }
00152 else
00153 ss << ps->getName().c_str() << "_pose_" << std::setfill('0') << std::setw(4) << goal_poses_.size();
00154 }
00155
00156 bool ok = false;
00157 QString text = QInputDialog::getText(this, tr("Choose a name"),
00158 tr("Goal pose name:"), QLineEdit::Normal,
00159 QString(ss.str().c_str()), &ok);
00160
00161 std::string name;
00162 if (ok)
00163 {
00164 if ( ! text.isEmpty() )
00165 {
00166 name = text.toStdString();
00167 if (goal_poses_.find(name) != goal_poses_.end())
00168 QMessageBox::warning(this, "Name already exists", QString("The name '").append(name.c_str()).
00169 append("' already exists. Not creating goal."));
00170 else
00171 {
00172
00173 scene_display_->getPlanningSceneRW()->getCurrentStateNonConst().update();
00174 Eigen::Affine3d tip_pose = scene_display_->getPlanningSceneRO()->getCurrentState().getGlobalLinkTransform(robot_interaction_->getActiveEndEffectors()[0].parent_link);
00175 createGoalAtPose(name, tip_pose);
00176 }
00177 }
00178 else
00179 QMessageBox::warning(this, "Goal not created", "Cannot use an empty name for a new goal pose.");
00180 }
00181
00182 populateGoalPosesList();
00183 }
00184
00185 void MainWindow::showBBoxGoalsDialog()
00186 {
00187 std::string goals_base_name;
00188 {
00189 const planning_scene_monitor::LockedPlanningSceneRO &ps = scene_display_->getPlanningSceneRO();
00190 if ( ! ps || robot_interaction_->getActiveEndEffectors().empty() )
00191 {
00192 if ( ! ps ) ROS_ERROR("No planning scene");
00193 if ( robot_interaction_->getActiveEndEffectors().empty() ) ROS_ERROR("No end effector");
00194 return;
00195 }
00196 goals_base_name = ps->getName() + "_pose_";
00197 }
00198
00199 bbox_dialog_ui_.base_name_text->setText(QString(goals_base_name.c_str()));
00200
00201 bbox_dialog_->exec();
00202 }
00203
00204 void MainWindow::createBBoxGoalsButtonClicked(void)
00205 {
00206 bbox_dialog_->close();
00207
00208 double minx = bbox_dialog_ui_.center_x_text->text().toDouble() - bbox_dialog_ui_.size_x_text->text().toDouble() / 2.0;
00209 double maxx = bbox_dialog_ui_.center_x_text->text().toDouble() + bbox_dialog_ui_.size_x_text->text().toDouble() / 2.0;
00210 double stepx = (maxx - minx) / std::max<double>(bbox_dialog_ui_.ngoals_x_text->text().toDouble() - 1, 1);
00211 double miny = bbox_dialog_ui_.center_y_text->text().toDouble() - bbox_dialog_ui_.size_y_text->text().toDouble() / 2.0;
00212 double maxy = bbox_dialog_ui_.center_y_text->text().toDouble() + bbox_dialog_ui_.size_y_text->text().toDouble() / 2.0;
00213 double stepy = (maxy - miny) / std::max<double>(bbox_dialog_ui_.ngoals_y_text->text().toDouble() - 1, 1);
00214 double minz = bbox_dialog_ui_.center_z_text->text().toDouble() - bbox_dialog_ui_.size_z_text->text().toDouble() / 2.0;
00215 double maxz = bbox_dialog_ui_.center_z_text->text().toDouble() + bbox_dialog_ui_.size_z_text->text().toDouble() / 2.0;
00216 double stepz = (maxz - minz) / std::max<double>(bbox_dialog_ui_.ngoals_z_text->text().toDouble() - 1, 1);
00217
00218 Eigen::Affine3d goal_pose;
00219 goal_pose.setIdentity();
00220 for (std::size_t x = 0; x < bbox_dialog_ui_.ngoals_x_text->text().toShort(); ++x)
00221 for (std::size_t y = 0; y < bbox_dialog_ui_.ngoals_y_text->text().toShort(); ++y)
00222 for (std::size_t z = 0; z < bbox_dialog_ui_.ngoals_z_text->text().toShort(); ++z)
00223 {
00224 goal_pose(0,3) = minx + x * stepx;
00225 goal_pose(1,3) = miny + y * stepy;
00226 goal_pose(2,3) = minz + z * stepz;
00227
00228 std::stringstream ss;
00229 ss << bbox_dialog_ui_.base_name_text->text().toStdString() << std::setfill('0') << std::setw(4) << goal_poses_.size();
00230
00231 createGoalAtPose(ss.str(), goal_pose);
00232 }
00233
00234 populateGoalPosesList();
00235 }
00236
00237 void MainWindow::removeSelectedGoalsButtonClicked(void)
00238 {
00239 QList<QListWidgetItem*> found_items = ui_.goal_poses_list->selectedItems();
00240 for ( unsigned int i = 0 ; i < found_items.size() ; i++ )
00241 {
00242 goal_poses_.erase(found_items[i]->text().toStdString());
00243 }
00244 populateGoalPosesList();
00245 }
00246
00247 void MainWindow::removeAllGoalsButtonClicked(void)
00248 {
00249 goal_poses_.clear();
00250 goals_initial_pose_.clear();
00251 populateGoalPosesList();
00252 }
00253
00254 void MainWindow::loadGoalsFromDBButtonClicked(void)
00255 {
00256
00257 if (constraints_storage_ && !robot_interaction_->getActiveEndEffectors().empty())
00258 {
00259
00260 removeAllGoalsButtonClicked();
00261
00262 std::vector<std::string> names;
00263 try
00264 {
00265 constraints_storage_->getKnownConstraints(ui_.load_poses_filter_text->text().toStdString(), names);
00266 }
00267 catch (std::runtime_error &ex)
00268 {
00269 QMessageBox::warning(this, "Cannot query the database", QString("Wrongly formatted regular expression for goal poses: ").append(ex.what()));
00270 return;
00271 }
00272
00273 for (unsigned int i = 0 ; i < names.size() ; i++)
00274 {
00275
00276 moveit_warehouse::ConstraintsWithMetadata c;
00277 bool got_constraint = false;
00278 try
00279 {
00280 got_constraint = constraints_storage_->getConstraints(c, names[i]);
00281 }
00282 catch (std::runtime_error &ex)
00283 {
00284 ROS_ERROR("%s", ex.what());
00285 }
00286 if (!got_constraint)
00287 continue;
00288
00289 if ( c->position_constraints.size() > 0 && c->position_constraints[0].constraint_region.primitive_poses.size() > 0 && c->orientation_constraints.size() > 0 )
00290 {
00291
00292 if ( goal_poses_.find(c->name) != goal_poses_.end() )
00293 {
00294 goal_poses_.erase(c->name);
00295 }
00296 geometry_msgs::Pose shape_pose;
00297 shape_pose.position = c->position_constraints[0].constraint_region.primitive_poses[0].position;
00298 shape_pose.orientation = c->orientation_constraints[0].orientation;
00299
00300 Eigen::Affine3d shape_pose_eigen;
00301 tf::poseMsgToEigen(shape_pose, shape_pose_eigen);
00302 goals_initial_pose_.insert(std::pair<std::string, Eigen::Affine3d>(c->name, shape_pose_eigen));
00303
00304 tf::poseEigenToMsg(shape_pose_eigen * goal_offset_, shape_pose);
00305
00306 static const float marker_scale = 0.15;
00307 GripperMarkerPtr goal_pose(new GripperMarker(scene_display_->getPlanningSceneRO()->getCurrentState(), scene_display_->getSceneNode(), visualization_manager_, c->name, scene_display_->getRobotModel()->getModelFrame(),
00308 robot_interaction_->getActiveEndEffectors()[0], shape_pose, marker_scale, GripperMarker::NOT_TESTED, false,
00309 ui_.show_x_checkbox->isChecked(), ui_.show_y_checkbox->isChecked(), ui_.show_z_checkbox->isChecked()));
00310
00311 goal_pose->connect(this, SLOT( goalPoseFeedback(visualization_msgs::InteractiveMarkerFeedback &) ));
00312
00313 goal_poses_.insert(GoalPosePair(c->name, goal_pose));
00314 }
00315 }
00316 populateGoalPosesList();
00317 }
00318 else
00319 {
00320 if (!constraints_storage_)
00321 QMessageBox::warning(this, "Warning", "Not connected to a database.");
00322 }
00323 }
00324
00325 void MainWindow::saveGoalsOnDBButtonClicked(void)
00326 {
00327 saveGoalsToDB();
00328 }
00329
00330 void MainWindow::deleteGoalsOnDBButtonClicked(void)
00331 {
00332 if (constraints_storage_)
00333 {
00334
00335 QMessageBox msgBox;
00336 msgBox.setText("All the selected items will be removed from the database");
00337 msgBox.setInformativeText("Do you want to continue?");
00338 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
00339 msgBox.setDefaultButton(QMessageBox::No);
00340 int ret = msgBox.exec();
00341
00342 switch (ret)
00343 {
00344 case QMessageBox::Yes:
00345 {
00346
00347 QList<QListWidgetItem*> found_items = ui_.goal_poses_list->selectedItems();
00348 for ( std::size_t i = 0 ; i < found_items.size() ; i++ )
00349 {
00350 try
00351 {
00352 constraints_storage_->removeConstraints(found_items[i]->text().toStdString());
00353 }
00354 catch (std::runtime_error &ex)
00355 {
00356 ROS_ERROR("%s", ex.what());
00357 }
00358 }
00359 break;
00360 }
00361 }
00362 }
00363 removeSelectedGoalsButtonClicked();
00364 }
00365
00366
00367 void MainWindow::loadStatesFromDBButtonClicked(void)
00368 {
00369
00370 if (robot_state_storage_)
00371 {
00372
00373 removeAllStatesButtonClicked();
00374
00375 std::vector<std::string> names;
00376 try
00377 {
00378 robot_state_storage_->getKnownRobotStates(ui_.load_states_filter_text->text().toStdString(), names);
00379 }
00380 catch (std::runtime_error &ex)
00381 {
00382 QMessageBox::warning(this, "Cannot query the database", QString("Wrongly formatted regular expression for goal poses: ").append(ex.what()));
00383 return;
00384 }
00385
00386 for ( unsigned int i = 0 ; i < names.size() ; i++ )
00387 {
00388 moveit_warehouse::RobotStateWithMetadata rs;
00389 bool got_state = false;
00390 try
00391 {
00392 got_state = robot_state_storage_->getRobotState(rs, names[i]);
00393 }
00394 catch(std::runtime_error &ex)
00395 {
00396 ROS_ERROR("%s", ex.what());
00397 }
00398 if (!got_state)
00399 continue;
00400
00401
00402 if (start_states_.find(names[i]) != start_states_.end())
00403 {
00404 start_states_.erase(names[i]);
00405 }
00406
00407
00408 start_states_.insert(StartStatePair(names[i], StartStatePtr(new StartState(*rs))));
00409 }
00410 populateStartStatesList();
00411 }
00412 else
00413 {
00414 QMessageBox::warning(this, "Warning", "Not connected to a database.");
00415 }
00416 }
00417
00418 void MainWindow::saveStatesOnDBButtonClicked(void)
00419 {
00420 if (robot_state_storage_)
00421 {
00422
00423 for (StartStateMap::iterator it = start_states_.begin(); it != start_states_.end(); ++it)
00424 try
00425 {
00426 robot_state_storage_->addRobotState(it->second->state_msg, it->first);
00427 }
00428 catch (std::runtime_error &ex)
00429 {
00430 ROS_ERROR("Cannot save robot state: %s", ex.what());
00431 }
00432 }
00433 else
00434 {
00435 QMessageBox::warning(this, "Warning", "Not connected to a database.");
00436 }
00437 }
00438
00439 void MainWindow::deleteStatesOnDBButtonClicked(void)
00440 {
00441 if (robot_state_storage_)
00442 {
00443
00444 QMessageBox msgBox;
00445 msgBox.setText("All the selected items will be removed from the database");
00446 msgBox.setInformativeText("Do you want to continue?");
00447 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
00448 msgBox.setDefaultButton(QMessageBox::No);
00449 int ret = msgBox.exec();
00450
00451 switch (ret)
00452 {
00453 case QMessageBox::Yes:
00454 {
00455 QList<QListWidgetItem*> found_items = ui_.start_states_list->selectedItems();
00456 for (unsigned int i = 0; i < found_items.size() ; ++i)
00457 {
00458 try
00459 {
00460 robot_state_storage_->removeRobotState(found_items[i]->text().toStdString());
00461 }
00462 catch (std::runtime_error &ex)
00463 {
00464 ROS_ERROR("%s", ex.what());
00465 }
00466 }
00467 break;
00468 }
00469 }
00470 }
00471 removeSelectedStatesButtonClicked();
00472 }
00473
00474 void MainWindow::visibleAxisChanged(int state)
00475 {
00476 if ( ! robot_interaction_->getActiveEndEffectors().empty() )
00477 {
00478 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00479 {
00480 if (it->second->isVisible())
00481 {
00482 it->second->setAxisVisibility(ui_.show_x_checkbox->isChecked(), ui_.show_y_checkbox->isChecked(), ui_.show_z_checkbox->isChecked());
00483 }
00484 }
00485 }
00486 }
00487
00488 void MainWindow::populateGoalPosesList(void)
00489 {
00490 ui_.goal_poses_list->clear();
00491 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00492 {
00493 QListWidgetItem *item = new QListWidgetItem(QString(it->first.c_str()));
00494 ui_.goal_poses_list->addItem(item);
00495 if (! it->second->isVisible())
00496 {
00497 item->setBackground(QBrush(Qt::Dense4Pattern));
00498 }
00499 else if (it->second->isSelected())
00500 {
00501
00502 item->setSelected(true);
00503 }
00504 }
00505 }
00506
00507 void MainWindow::switchGoalVisibilityButtonClicked(void)
00508 {
00509 QList<QListWidgetItem*> selection = ui_.goal_poses_list->selectedItems();
00510 for (std::size_t i = 0; i < selection.size() ; ++i)
00511 {
00512 std::string name = selection[i]->text().toStdString();
00513 if (goal_poses_[name]->isVisible())
00514 {
00515
00516 goal_poses_[name]->hide();
00517 selection[i]->setBackground(QBrush(Qt::Dense4Pattern));
00518 }
00519 else
00520 {
00521
00522 goal_poses_[name]->show(scene_display_->getSceneNode(), visualization_manager_);
00523 selection[i]->setBackground(QBrush(Qt::NoBrush));
00524 }
00525 }
00526 }
00527
00528 void MainWindow::goalPoseSelectionChanged(void)
00529 {
00530 for (unsigned int i = 0; i < ui_.goal_poses_list->count() ; ++i)
00531 {
00532 QListWidgetItem *item = ui_.goal_poses_list->item(i);
00533 std::string name = item->text().toStdString();
00534 if ( goal_poses_.find(name) != goal_poses_.end() &&
00535 ( (item->isSelected() && ! goal_poses_[name]->isSelected() )
00536 || ( ! item->isSelected() && goal_poses_[name]->isSelected() )))
00537 switchGoalPoseMarkerSelection(name);
00538 }
00539 }
00540
00541 void MainWindow::goalPoseDoubleClicked(QListWidgetItem * item)
00542 {
00543 JobProcessing::addBackgroundJob(boost::bind(&MainWindow::computeGoalPoseDoubleClicked, this, item));
00544 }
00545
00546 void MainWindow::computeGoalPoseDoubleClicked(QListWidgetItem * item)
00547 {
00548 if ( ! robot_interaction_ || robot_interaction_->getActiveEndEffectors().empty() )
00549 return;
00550
00551 std::string item_text = item->text().toStdString();
00552
00553
00554 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, item_text, GripperMarker::PROCESSING));
00555
00556 checkIfGoalReachable(item_text, true);
00557 }
00558
00559
00560 void MainWindow::goalPoseFeedback(visualization_msgs::InteractiveMarkerFeedback &feedback)
00561 {
00562 if (feedback.event_type == feedback.BUTTON_CLICK)
00563 {
00564
00565 QListWidgetItem *item = 0;
00566 for (unsigned int i = 0; i < ui_.goal_poses_list->count(); ++i)
00567 {
00568 item = ui_.goal_poses_list->item(i);
00569 if ( item->text().toStdString() != feedback.marker_name)
00570 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::selectItemJob, this, item, false));
00571 }
00572
00573 for (unsigned int i = 0; i < ui_.goal_poses_list->count(); ++i)
00574 {
00575 item = ui_.goal_poses_list->item(i);
00576 if (item->text().toStdString() == feedback.marker_name)
00577 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::selectItemJob, this, item, true));
00578 }
00579 }
00580 else if (feedback.event_type == feedback.MOUSE_DOWN)
00581 {
00582
00583
00584
00585 bool this_goal_already_selected = false;
00586 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00587 {
00588 if (it->second->isSelected() &&
00589 it->second->isVisible() &&
00590 it->second->imarker->getName() == feedback.marker_name)
00591 {
00592 this_goal_already_selected = true;
00593 }
00594 }
00595
00596
00597
00598
00599 if(this_goal_already_selected) {
00600
00601 goals_dragging_initial_pose_.clear();
00602 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00603 {
00604 if (it->second->isSelected() && it->second->isVisible())
00605 {
00606 Eigen::Affine3d pose(Eigen::Quaterniond(it->second->imarker->getOrientation().w, it->second->imarker->getOrientation().x,
00607 it->second->imarker->getOrientation().y, it->second->imarker->getOrientation().z));
00608 pose(0,3) = it->second->imarker->getPosition().x;
00609 pose(1,3) = it->second->imarker->getPosition().y;
00610 pose(2,3) = it->second->imarker->getPosition().z;
00611 goals_dragging_initial_pose_.insert(std::pair<std::string, Eigen::Affine3d>(it->second->imarker->getName(), pose));
00612
00613 if (it->second->imarker->getName() == feedback.marker_name)
00614 drag_initial_pose_ = pose;
00615 }
00616 }
00617 goal_pose_dragging_=true;
00618 }
00619 }
00620 else if (feedback.event_type == feedback.POSE_UPDATE && goal_pose_dragging_)
00621 {
00622
00623 Eigen::Affine3d current_pose_eigen;
00624 tf::poseMsgToEigen(feedback.pose, current_pose_eigen);
00625
00626 Eigen::Affine3d current_wrt_initial = drag_initial_pose_.inverse() * current_pose_eigen;
00627
00628
00629 Eigen::Vector3d v = current_pose_eigen.linear().eulerAngles(0,1,2);
00630 setStatusFromBackground(STATUS_INFO, QString().sprintf(
00631 "%.2f %.2f %.2f %.2f %.2f %.2f",
00632 current_pose_eigen(0,3),
00633 current_pose_eigen(1,3),
00634 current_pose_eigen(2,3),
00635 v(0) * 180.0 / boost::math::constants::pi<double>(),
00636 v(1) * 180.0 / boost::math::constants::pi<double>(),
00637 v(2) * 180.0 / boost::math::constants::pi<double>()));
00638
00639
00640 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end() ; ++it)
00641 {
00642 if (it->second->isVisible() && it->second->imarker->getName() != feedback.marker_name && it->second->isSelected())
00643 {
00644 visualization_msgs::InteractiveMarkerPose impose;
00645
00646 Eigen::Affine3d newpose = drag_initial_pose_ * current_wrt_initial * drag_initial_pose_.inverse() * goals_dragging_initial_pose_[it->second->imarker->getName()];
00647 tf::poseEigenToMsg(newpose, impose.pose);
00648
00649 it->second->imarker->setPose(Ogre::Vector3(impose.pose.position.x, impose.pose.position.y, impose.pose.position.z),
00650 Ogre::Quaternion(impose.pose.orientation.w, impose.pose.orientation.x, impose.pose.orientation.y, impose.pose.orientation.z), "");
00651 }
00652 }
00653 } else if (feedback.event_type == feedback.MOUSE_UP)
00654 {
00655 goal_pose_dragging_ = false;
00656 JobProcessing::addBackgroundJob(boost::bind(&MainWindow::checkIfGoalInCollision, this, feedback.marker_name));
00657 }
00658 }
00659
00660 void MainWindow::checkGoalsReachable(void)
00661 {
00662 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00663 JobProcessing::addBackgroundJob(boost::bind(&MainWindow::checkIfGoalReachable, this, it->first, false));
00664 }
00665
00666 void MainWindow::checkGoalsInCollision(void)
00667 {
00668 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
00669 JobProcessing::addBackgroundJob(boost::bind(&MainWindow::checkIfGoalInCollision, this, it->first));
00670 }
00671
00672 void MainWindow::checkIfGoalReachable(const std::string &goal_name, bool update_if_reachable)
00673 {
00674 if ( goal_poses_.find(goal_name) == goal_poses_.end())
00675 return;
00676
00677 if ( ! goal_poses_[goal_name]->isVisible())
00678 return;
00679
00680 const boost::shared_ptr<rviz::InteractiveMarker> &imarker = goal_poses_[goal_name]->imarker;
00681
00682 geometry_msgs::Pose current_pose_msg;
00683 current_pose_msg.position.x = imarker->getPosition().x;
00684 current_pose_msg.position.y = imarker->getPosition().y;
00685 current_pose_msg.position.z = imarker->getPosition().z;
00686 current_pose_msg.orientation.x = imarker->getOrientation().x;
00687 current_pose_msg.orientation.y = imarker->getOrientation().y;
00688 current_pose_msg.orientation.z = imarker->getOrientation().z;
00689 current_pose_msg.orientation.w = imarker->getOrientation().w;
00690
00691
00692 setStatusFromBackground(STATUS_INFO, "Computing inverse kinematics...");
00693 robot_state::RobotState ks(scene_display_->getPlanningSceneRO()->getCurrentState());
00694 static const int ik_attempts = 5;
00695 static const float ik_timeout = 0.2;
00696 bool feasible = robot_interaction_->updateState(ks,
00697 robot_interaction_->getActiveEndEffectors()[0],
00698 current_pose_msg, ik_attempts, ik_timeout);
00699 if (feasible)
00700 {
00701 setStatusFromBackground(STATUS_INFO, "Updating state...");
00702 if (update_if_reachable)
00703 {
00704 scene_display_->getPlanningSceneRW()->setCurrentState(ks);
00705 scene_display_->queueRenderSceneGeometry();
00706 }
00707
00708 setStatusFromBackground(STATUS_INFO, "Updating marker...");
00709
00710 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
00711 GripperMarker::REACHABLE));
00712 }
00713 else
00714 {
00715
00716 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
00717 GripperMarker::NOT_REACHABLE));
00718 }
00719 setStatusFromBackground(STATUS_INFO, "");
00720 }
00721
00722 bool MainWindow::isGroupCollidingWithWorld(robot_state::RobotState& robot_state, const std::string& group_name)
00723 {
00724 collision_detection::AllowedCollisionMatrix acm( scene_display_->getPlanningSceneRO()->getAllowedCollisionMatrix() );
00725
00726 const std::vector<std::string>& group_link_names =
00727 scene_display_->getRobotModel()->getJointModelGroup(group_name)->getLinkModelNamesWithCollisionGeometry();
00728
00729
00730 const std::vector<std::string>& all_links = scene_display_->getRobotModel()->getLinkModelNames();
00731 std::set<std::string> link_set(all_links.begin(), all_links.end());
00732 for(size_t i = 0; i < group_link_names.size(); i++ )
00733 {
00734 link_set.erase(group_link_names[i]);
00735 }
00736
00737
00738 for(std::set<std::string>::const_iterator it = link_set.begin(); it != link_set.end(); it++ )
00739 {
00740
00741 acm.setEntry(*it, true);
00742 }
00743
00744
00745 collision_detection::CollisionRequest req;
00746 req.verbose = false;
00747 collision_detection::CollisionResult res;
00748 scene_display_->getPlanningSceneRO()->checkCollision(req, res, robot_state, acm);
00749
00750
00751 return res.collision;
00752 }
00753
00754 void MainWindow::checkIfGoalInCollision(const std::string & goal_name)
00755 {
00756 if ( goal_poses_.find(goal_name) == goal_poses_.end())
00757 return;
00758
00759
00760 if ( ! goal_poses_[goal_name]->isVisible())
00761 return;
00762
00763 const robot_interaction::RobotInteraction::EndEffector &eef = robot_interaction_->getActiveEndEffectors()[0];
00764
00765 const boost::shared_ptr<rviz::InteractiveMarker> &im = goal_poses_[goal_name]->imarker;
00766 Eigen::Affine3d marker_pose_eigen;
00767 goal_poses_[goal_name]->getPose(marker_pose_eigen);
00768
00769 robot_state::RobotState ks(scene_display_->getPlanningSceneRO()->getCurrentState());
00770 ks.updateStateWithLinkAt(eef.parent_link, marker_pose_eigen);
00771 bool in_collision = isGroupCollidingWithWorld(ks, eef.eef_group);
00772
00773 if ( in_collision )
00774 {
00775 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
00776 GripperMarker::IN_COLLISION));
00777 }
00778 else
00779 {
00780 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
00781 GripperMarker::NOT_TESTED));
00782 }
00783 }
00784
00785 void MainWindow::switchGoalPoseMarkerSelection(const std::string &marker_name)
00786 {
00787 if (robot_interaction_->getActiveEndEffectors().empty() || ! goal_poses_[marker_name]->isVisible())
00788 return;
00789
00790 if (goal_poses_[marker_name]->isSelected())
00791 {
00792
00793 goal_poses_[marker_name]->unselect();
00794 setItemSelectionInList(marker_name, false, ui_.goal_poses_list);
00795 }
00796 else
00797 {
00798
00799 if (ui_.goal_poses_list->selectedItems().size() == 1)
00800 goal_poses_[marker_name]->select(true);
00801 else
00802 goal_poses_[marker_name]->select(false);
00803 setItemSelectionInList(marker_name, true, ui_.goal_poses_list);
00804 }
00805 }
00806
00807 void MainWindow::copySelectedGoalPoses(void)
00808 {
00809 QList<QListWidgetItem *> sel = ui_.goal_poses_list->selectedItems();
00810 if (sel.empty() || robot_interaction_->getActiveEndEffectors().empty())
00811 return;
00812
00813 std::string scene_name;
00814 {
00815 const planning_scene_monitor::LockedPlanningSceneRO &ps = scene_display_->getPlanningSceneRO();
00816 if (!ps)
00817 return;
00818 else
00819 scene_name = ps->getName();
00820 }
00821
00822 for (int i = 0 ; i < sel.size() ; ++i)
00823 {
00824 std::string name = sel[i]->text().toStdString();
00825 if (! goal_poses_[name]->isVisible())
00826 continue;
00827
00828 std::stringstream ss;
00829 ss << scene_name.c_str() << "_pose_" << std::setfill('0') << std::setw(4) << goal_poses_.size();
00830
00831 scene_display_->getPlanningSceneRW()->getCurrentStateNonConst().update();
00832 Eigen::Affine3d tip_pose = scene_display_->getPlanningSceneRO()->getCurrentState().getGlobalLinkTransform(robot_interaction_->getActiveEndEffectors()[0].parent_link);
00833 geometry_msgs::Pose marker_pose;
00834 marker_pose.position.x = goal_poses_[name]->imarker->getPosition().x;
00835 marker_pose.position.y = goal_poses_[name]->imarker->getPosition().y;
00836 marker_pose.position.z = goal_poses_[name]->imarker->getPosition().z;
00837 marker_pose.orientation.x = goal_poses_[name]->imarker->getOrientation().x;
00838 marker_pose.orientation.y = goal_poses_[name]->imarker->getOrientation().y;
00839 marker_pose.orientation.z = goal_poses_[name]->imarker->getOrientation().z;
00840 marker_pose.orientation.w = goal_poses_[name]->imarker->getOrientation().w;
00841
00842 static const float marker_scale = 0.15;
00843 GripperMarkerPtr goal_pose(new GripperMarker(scene_display_->getPlanningSceneRO()->getCurrentState(), scene_display_->getSceneNode(), visualization_manager_, ss.str(), scene_display_->getRobotModel()->getModelFrame(),
00844 robot_interaction_->getActiveEndEffectors()[0], marker_pose, marker_scale, GripperMarker::NOT_TESTED, true));
00845
00846 goal_poses_.insert(GoalPosePair(ss.str(), goal_pose));
00847
00848
00849 goal_pose->connect(this, SLOT( goalPoseFeedback(visualization_msgs::InteractiveMarkerFeedback &)));
00850
00851
00852 switchGoalPoseMarkerSelection(name);
00853 }
00854
00855 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::populateGoalPosesList, this));
00856 }
00857
00858 void MainWindow::saveStartStateButtonClicked(void)
00859 {
00860 bool ok = false;
00861
00862 std::stringstream ss;
00863 ss << scene_display_->getRobotModel()->getName().c_str() << "_state_" << std::setfill('0') << std::setw(4) << start_states_.size();
00864
00865 QString text = QInputDialog::getText(this, tr("Choose a name"),
00866 tr("Start state name:"), QLineEdit::Normal,
00867 QString(ss.str().c_str()), &ok);
00868
00869 std::string name;
00870 if (ok)
00871 {
00872 if (!text.isEmpty())
00873 {
00874 name = text.toStdString();
00875 if (start_states_.find(name) != start_states_.end())
00876 QMessageBox::warning(this, "Name already exists", QString("The name '").append(name.c_str()).
00877 append("' already exists. Not creating state."));
00878 else
00879 {
00880
00881 moveit_msgs::RobotState msg;
00882 robot_state::robotStateToRobotStateMsg(scene_display_->getPlanningSceneRO()->getCurrentState(), msg);
00883 start_states_.insert(StartStatePair(name, StartStatePtr(new StartState(msg))));
00884
00885
00886 if (robot_state_storage_)
00887 {
00888 try
00889 {
00890 robot_state_storage_->addRobotState(msg, name);
00891 }
00892 catch (std::runtime_error &ex)
00893 {
00894 ROS_ERROR("Cannot save robot state on the database: %s", ex.what());
00895 }
00896 }
00897 }
00898 }
00899 else
00900 QMessageBox::warning(this, "Start state not saved", "Cannot use an empty name for a new start state.");
00901 }
00902 populateStartStatesList();
00903 }
00904
00905 void MainWindow::removeSelectedStatesButtonClicked(void)
00906 {
00907 QList<QListWidgetItem*> found_items = ui_.start_states_list->selectedItems();
00908 for (unsigned int i = 0; i < found_items.size(); i++)
00909 {
00910 start_states_.erase(found_items[i]->text().toStdString());
00911 }
00912 populateStartStatesList();
00913 }
00914
00915 void MainWindow::removeAllStatesButtonClicked(void)
00916 {
00917 start_states_.clear();
00918 populateStartStatesList();
00919 }
00920
00921 void MainWindow::populateStartStatesList(void)
00922 {
00923 ui_.start_states_list->clear();
00924 for (StartStateMap::iterator it = start_states_.begin(); it != start_states_.end(); ++it)
00925 {
00926 QListWidgetItem *item = new QListWidgetItem(QString(it->first.c_str()));
00927 ui_.start_states_list->addItem(item);
00928 if (it->second->selected)
00929 {
00930
00931 item->setSelected(true);
00932 }
00933 }
00934 }
00935
00936 void MainWindow::startStateItemDoubleClicked(QListWidgetItem * item)
00937 {
00938 scene_display_->getPlanningSceneRW()->setCurrentState(start_states_[item->text().toStdString()]->state_msg);
00939 scene_display_->queueRenderSceneGeometry();
00940 }
00941
00942 void MainWindow::runBenchmark(void)
00943 {
00944 if (! robot_interaction_ || robot_interaction_->getActiveEndEffectors().size() == 0)
00945 {
00946 QMessageBox::warning(this, "Error", "Please make sure a planning group with an end-effector is active");
00947 return;
00948 }
00949
00950 run_benchmark_ui_.benchmark_goal_text->setText(ui_.load_poses_filter_text->text());
00951 run_benchmark_ui_.benchmark_start_state_text->setText(ui_.load_states_filter_text->text());
00952
00953
00954 boost::shared_ptr<pluginlib::ClassLoader<planning_interface::PlannerManager> > planner_plugin_loader;
00955 std::map<std::string, planning_interface::PlannerManagerPtr> planner_interfaces;
00956 try
00957 {
00958 planner_plugin_loader.reset(new pluginlib::ClassLoader<planning_interface::PlannerManager>("moveit_core", "planning_interface::PlannerManager"));
00959 }
00960 catch(pluginlib::PluginlibException& ex)
00961 {
00962 ROS_FATAL_STREAM("Exception while creating planning plugin loader " << ex.what());
00963 }
00964
00965 if (planner_plugin_loader)
00966 {
00967
00968 const std::vector<std::string> &classes = planner_plugin_loader->getDeclaredClasses();
00969 for (std::size_t i = 0 ; i < classes.size() ; ++i)
00970 {
00971 ROS_DEBUG("Attempting to load and configure %s", classes[i].c_str());
00972 try
00973 {
00974 boost::shared_ptr<planning_interface::PlannerManager> p = planner_plugin_loader->createInstance(classes[i]);
00975 p->initialize(scene_display_->getPlanningSceneRO()->getRobotModel(), "");
00976 planner_interfaces[classes[i]] = p;
00977 }
00978 catch (pluginlib::PluginlibException& ex)
00979 {
00980 ROS_ERROR_STREAM("Exception while loading planner '" << classes[i] << "': " << ex.what());
00981 }
00982 }
00983
00984
00985 if (! planner_interfaces.empty())
00986 {
00987 std::stringstream interfaces_ss, algorithms_ss;
00988 for (std::map<std::string, boost::shared_ptr<planning_interface::PlannerManager> >::const_iterator it = planner_interfaces.begin() ;
00989 it != planner_interfaces.end(); ++it)
00990 {
00991 interfaces_ss << it->first << " ";
00992
00993 std::vector<std::string> known;
00994 it->second->getPlanningAlgorithms(known);
00995 for (std::size_t i = 0; i < known.size(); ++i)
00996 algorithms_ss << known[i] << " ";
00997 }
00998 ROS_DEBUG("Available planner instances: %s. Available algorithms: %s", interfaces_ss.str().c_str(), algorithms_ss.str().c_str());
00999 run_benchmark_ui_.planning_interfaces_text->setText(QString(interfaces_ss.str().c_str()));
01000 run_benchmark_ui_.planning_algorithms_text->setText(QString(algorithms_ss.str().c_str()));
01001 }
01002 }
01003
01004 run_benchmark_dialog_->show();
01005 }
01006
01007 void MainWindow::benchmarkFolderButtonClicked(void)
01008 {
01009 QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
01010 "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
01011 run_benchmark_ui_.benchmark_output_folder_text->setText(dir);
01012 }
01013
01014 void MainWindow::cancelBenchmarkButtonClicked(void)
01015 {
01016 run_benchmark_dialog_->close();
01017 }
01018
01019 bool MainWindow::saveBenchmarkConfigButtonClicked(void)
01020 {
01021 if (run_benchmark_ui_.benchmark_output_folder_text->text().isEmpty())
01022 {
01023 QMessageBox::warning(this, "Missing data", "Must specify an output folder");
01024 return false;
01025 }
01026
01027 QString outfilename = run_benchmark_ui_.benchmark_output_folder_text->text().append("/config.cfg");
01028 std::ofstream outfile(outfilename.toUtf8());
01029 if (outfile)
01030 {
01031 outfile << "[scene]" << std::endl;
01032 outfile << "group=" << ui_.planning_group_combo->currentText().toStdString() << std::endl;
01033 outfile << "default_constrained_link=" << robot_interaction_->getActiveEndEffectors()[0].parent_link << std::endl;
01034 outfile << "planning_frame=" << scene_display_->getPlanningSceneMonitor()->getRobotModel()->getModelFrame() << std::endl;
01035 outfile << "name=" << scene_display_->getPlanningSceneRO()->getName() << std::endl;
01036
01037 outfile << "timeout=" << run_benchmark_ui_.timeout_spin->value() << std::endl;
01038 outfile << "runs=" << run_benchmark_ui_.number_of_runs_spin->value() << std::endl;
01039 outfile << "output=" << run_benchmark_ui_.benchmark_output_folder_text->text().toStdString() << "/" << scene_display_->getPlanningSceneMonitor()->getRobotModel()->getName() << "_" <<
01040 scene_display_->getPlanningSceneRO()->getName() << "_" <<
01041 ros::Time::now() << std::endl;
01042 outfile << "start=" << run_benchmark_ui_.benchmark_start_state_text->text().toStdString() << std::endl;
01043 outfile << "query=" << std::endl;
01044 outfile << "goal=" << run_benchmark_ui_.benchmark_goal_text->text().toStdString() << std::endl;
01045 outfile << "goal_offset_roll=" << ui_.goal_offset_roll->value() << std::endl;
01046 outfile << "goal_offset_pitch=" << ui_.goal_offset_pitch->value() << std::endl;
01047 outfile << "goal_offset_yaw=" << ui_.goal_offset_yaw->value() << std::endl << std::endl;
01048
01049 outfile << "[plugin]" << std::endl;
01050 outfile << "name=" << run_benchmark_ui_.planning_interfaces_text->text().toStdString() << std::endl;
01051 outfile << "planners=" << run_benchmark_ui_.planning_algorithms_text->text().toStdString() << std::endl;
01052
01053 outfile.close();
01054
01055 run_benchmark_dialog_->close();
01056 }
01057 else
01058 {
01059 QMessageBox::warning(this, "Error", QString("Cannot open file ").append(outfilename).append(" for writing"));
01060 return false;
01061 }
01062
01063 return true;
01064 }
01065
01066 void MainWindow::runBenchmarkButtonClicked(void)
01067 {
01068 if (! saveBenchmarkConfigButtonClicked())
01069 return;
01070
01071 QMessageBox msgBox;
01072 msgBox.setText("This will run the benchmark pipeline. The process will take several minutes during which you will not be able to interact with the interface. You can follow the progress in the console output");
01073 msgBox.setInformativeText("Do you want to continue?");
01074 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
01075 msgBox.setDefaultButton(QMessageBox::Yes);
01076 int ret = msgBox.exec();
01077
01078 switch (ret)
01079 {
01080 case QMessageBox::Yes:
01081 {
01082 QString outfilename = run_benchmark_ui_.benchmark_output_folder_text->text().append("/config.cfg");
01083 moveit_benchmarks::BenchmarkType btype = 0;
01084 moveit_benchmarks::BenchmarkExecution be(scene_display_->getPlanningSceneMonitor()->getPlanningScene(), database_host_, database_port_);
01085 if (run_benchmark_ui_.benchmark_include_planners_checkbox->isChecked())
01086 btype += moveit_benchmarks::BENCHMARK_PLANNERS;
01087 if (run_benchmark_ui_.benchmark_check_reachability_checkbox->isChecked())
01088 btype += moveit_benchmarks::BENCHMARK_GOAL_EXISTANCE;
01089
01090 if (be.readOptions(outfilename.toStdString()))
01091 {
01092 std::stringstream ss;
01093 be.printOptions(ss);
01094 ROS_INFO_STREAM("Calling benchmark with options:" << std::endl << ss.str() << std::endl);
01095
01096 BenchmarkProcessingThread benchmark_thread(be, btype, this);
01097 benchmark_thread.startAndShow();
01098
01099 if (benchmark_thread.isRunning())
01100 {
01101 benchmark_thread.terminate();
01102 benchmark_thread.wait();
01103 QMessageBox::warning(this, "", "Benchmark computation canceled");
01104 }
01105 else
01106 {
01107 QMessageBox::information(this, "Benchmark computation finished", QString("The results were logged into '").append(run_benchmark_ui_.benchmark_output_folder_text->text()));
01108 }
01109 }
01110
01111 break;
01112 }
01113 }
01114 }
01115
01116 void MainWindow::loadBenchmarkResults(void)
01117 {
01118
01119 QString path = QFileDialog::getOpenFileName(this, tr("Select a log file in the set"), tr(""), tr("Log files (*.log)"));
01120 if (!path.isEmpty())
01121 {
01122 JobProcessing::addBackgroundJob(boost::bind(&MainWindow::computeLoadBenchmarkResults, this, path.toStdString()));
01123 }
01124 }
01125
01126 void MainWindow::computeLoadBenchmarkResults(const std::string &file)
01127 {
01128 std::string logid, basename, logid_text;
01129 try
01130 {
01131 logid = file.substr( file.find_last_of(".", file.length()-5) + 1, file.find_last_of(".") - file.find_last_of(".", file.length()-5) - 1 );
01132 basename = file.substr(0, file.find_last_of(".", file.length()-5));
01133 logid_text = logid.substr(logid.find_first_of("_"), logid.length() - logid.find_first_of("_"));
01134 }
01135 catch (...)
01136 {
01137 ROS_ERROR("Invalid benchmark log file. Cannot load results.");
01138 return;
01139 }
01140
01141 int count = 1;
01142 bool more_files = true;
01143
01144 while (more_files)
01145 {
01146 std::ifstream ifile;
01147 std::stringstream file_to_load;
01148 file_to_load << basename << "." << count << logid_text << ".log";
01149
01150 ifile.open(file_to_load.str().c_str());
01151 if (ifile.good())
01152 {
01153
01154 char text_line[512];
01155 static std::streamsize text_line_length = 512;
01156 bool valid_file = false;
01157 ifile.getline(text_line, text_line_length);
01158
01159
01160 if (ifile.good() && strstr(text_line, "Experiment") != NULL && strlen(text_line) > 11
01161 && strncmp(&text_line[11], scene_display_->getPlanningSceneRO()->getName().c_str(), scene_display_->getPlanningSceneRO()->getName().length()) == 0)
01162 {
01163 while (ifile.good())
01164 {
01165 if ( strstr(text_line, "total_time REAL") != NULL)
01166 {
01167 valid_file = true;
01168 break;
01169 }
01170
01171 ifile.getline(text_line, text_line_length);
01172 }
01173 }
01174 else
01175 {
01176 ROS_ERROR("Not a valid log file, or a different planning scene loaded");
01177 }
01178
01179 if (valid_file)
01180 {
01181 if (basename.find(".trajectory") != std::string::npos)
01182 {
01183
01184 int nwaypoint = 0;
01185 while (ifile.getline(text_line, text_line_length) && ifile.good() && strlen(text_line) > 6)
01186 {
01187
01188 try
01189 {
01190 bool reachable = boost::lexical_cast<bool>(text_line[0]);
01191 bool collision_free = boost::lexical_cast<bool>(text_line[3]);
01192
01193
01194
01195 if (count <= trajectories_.size())
01196 {
01197 std::string trajectory_name = ui_.trajectory_list->item(count-1)->text().toStdString();
01198 if ( nwaypoint < trajectories_[trajectory_name]->waypoint_markers.size() )
01199 {
01200 if (reachable)
01201 {
01202 if (collision_free)
01203 {
01204
01205 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateMarkerState, this, trajectories_[trajectory_name]->waypoint_markers[nwaypoint],
01206 GripperMarker::REACHABLE));
01207 }
01208 else
01209 {
01210
01211 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateMarkerState, this, trajectories_[trajectory_name]->waypoint_markers[nwaypoint],
01212 GripperMarker::IN_COLLISION));
01213 }
01214 }
01215 else
01216 {
01217
01218 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateMarkerState, this, trajectories_[trajectory_name]->waypoint_markers[nwaypoint],
01219 GripperMarker::NOT_REACHABLE));
01220 }
01221 }
01222 }
01223 nwaypoint++;
01224 }
01225 catch (...)
01226 {
01227 ROS_ERROR("Error parsing the log file");
01228 }
01229 }
01230 }
01231 else
01232 {
01233 ifile.getline(text_line, text_line_length);
01234 if (ifile.good() && strlen(text_line) > 6)
01235 {
01236
01237 try
01238 {
01239 bool reachable = boost::lexical_cast<bool>(text_line[0]);
01240 bool collision_free = boost::lexical_cast<bool>(text_line[3]);
01241
01242
01243 if (count <= goal_poses_.size())
01244 {
01245 std::string goal_name = ui_.goal_poses_list->item(count-1)->text().toStdString();
01246 if (reachable)
01247 {
01248 if (collision_free)
01249 {
01250
01251 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
01252 GripperMarker::REACHABLE));
01253 }
01254 else
01255 {
01256
01257 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
01258 GripperMarker::IN_COLLISION));
01259 }
01260 }
01261 else
01262 {
01263
01264 JobProcessing::addMainLoopJob(boost::bind(&MainWindow::updateGoalMarkerStateFromName, this, goal_name,
01265 GripperMarker::NOT_REACHABLE));
01266 }
01267 }
01268 }
01269 catch (...)
01270 {
01271 ROS_ERROR("Error parsing the log file");
01272 }
01273 }
01274 }
01275 }
01276 else
01277 {
01278 ROS_ERROR("Invalid benchmark log file. Cannot load results.");
01279 }
01280
01281 ifile.close();
01282 }
01283 else
01284 {
01285 more_files = false;
01286 }
01287 count++;
01288 }
01289 }
01290
01291 void MainWindow::updateGoalMarkerStateFromName(const std::string &name, const GripperMarker::GripperMarkerState &state)
01292 {
01293 if ( goal_poses_.find(name) != goal_poses_.end())
01294 goal_poses_[name]->setState(state);
01295 }
01296
01297 void MainWindow::updateMarkerState(GripperMarkerPtr marker, const GripperMarker::GripperMarkerState &state)
01298 {
01299 marker->setState(state);
01300 }
01301
01302 void MainWindow::goalOffsetChanged()
01303 {
01304 goal_offset_.setIdentity();
01305 goal_offset_ = Eigen::AngleAxisd(ui_.goal_offset_roll->value() * boost::math::constants::pi<double>() / 180.0, Eigen::Vector3d::UnitX()) *
01306 Eigen::AngleAxisd(ui_.goal_offset_pitch->value() * boost::math::constants::pi<double>() / 180.0, Eigen::Vector3d::UnitY()) *
01307 Eigen::AngleAxisd(ui_.goal_offset_yaw->value() * boost::math::constants::pi<double>() / 180.0, Eigen::Vector3d::UnitZ());
01308
01309 if ( ! robot_interaction_->getActiveEndEffectors().empty() )
01310 {
01311 Eigen::Affine3d current_pose;
01312 for (GoalPoseMap::iterator it = goal_poses_.begin(); it != goal_poses_.end(); ++it)
01313 {
01314 current_pose = goals_initial_pose_[it->first] * goal_offset_;
01315 it->second->setPose(current_pose);
01316 }
01317 }
01318 }
01319
01320 }