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 <trajectory.h>
00039 #include <job_processing.h>
00040 #include <ui_utils.h>
00041
00042 #include <eigen_conversions/eigen_msg.h>
00043
00044 #include <QMessageBox>
00045 #include <QInputDialog>
00046
00047 #include <boost/math/constants/constants.hpp>
00048
00049 namespace benchmark_tool
00050 {
00051
00052 void MainWindow::createTrajectoryButtonClicked(void)
00053 {
00054 std::stringstream ss;
00055
00056 {
00057 const planning_scene_monitor::LockedPlanningSceneRO &ps = scene_display_->getPlanningSceneRO();
00058 if ( ! ps || robot_interaction_->getActiveEndEffectors().empty() )
00059 {
00060 if ( ! ps ) ROS_ERROR("Not planning scene");
00061 if ( robot_interaction_->getActiveEndEffectors().empty() ) ROS_ERROR("No end effector");
00062 return;
00063 }
00064 else
00065 ss << ps->getName().c_str() << "_trajectory_" << std::setfill('0') << std::setw(4) << trajectories_.size();
00066 }
00067
00068 bool ok = false;
00069 QString text = QInputDialog::getText(this, tr("Choose a name"),
00070 tr("Trajectory name:"), QLineEdit::Normal,
00071 QString(ss.str().c_str()), &ok);
00072
00073 std::string name;
00074 if (ok)
00075 {
00076 if ( ! text.isEmpty() )
00077 {
00078 name = text.toStdString();
00079 if (goal_poses_.find(name) != goal_poses_.end())
00080 QMessageBox::warning(this, "Name already exists", QString("The name '").append(name.c_str()).
00081 append("' already exists. Not creating trajectory."));
00082 else
00083 {
00084
00085 scene_display_->getPlanningSceneRW()->getCurrentStateNonConst().update();
00086 Eigen::Affine3d tip_pose = scene_display_->getPlanningSceneRO()->getCurrentState().getGlobalLinkTransform(robot_interaction_->getActiveEndEffectors()[0].parent_link);
00087 geometry_msgs::Pose marker_pose;
00088 tf::poseEigenToMsg(tip_pose, marker_pose);
00089 static const float marker_scale = 0.15;
00090
00091 TrajectoryPtr trajectory_marker( new Trajectory(scene_display_->getPlanningSceneRO()->getCurrentState(), scene_display_->getSceneNode(), visualization_manager_,
00092 name, scene_display_->getRobotModel()->getModelFrame(),
00093 robot_interaction_->getActiveEndEffectors()[0], marker_pose, marker_scale, GripperMarker::NOT_TESTED,
00094 ui_.trajectory_nwaypoints_spin->value()));
00095
00096 trajectories_.insert(TrajectoryPair(name, trajectory_marker));
00097 }
00098 }
00099 else
00100 QMessageBox::warning(this, "Goal not created", "Cannot use an empty name for a new goal pose.");
00101 }
00102
00103 populateTrajectoriesList();
00104 selectLastItemInList(ui_.trajectory_list);
00105 }
00106
00107 void MainWindow::populateTrajectoriesList(void)
00108 {
00109 bool old_signal_state = ui_.trajectory_list->blockSignals(true);
00110 ui_.trajectory_list->clear();
00111 for (TrajectoryMap::iterator it = trajectories_.begin(); it != trajectories_.end(); ++it)
00112 {
00113 QListWidgetItem *item = new QListWidgetItem(QString(it->first.c_str()));
00114 ui_.trajectory_list->addItem(item);
00115 }
00116 ui_.trajectory_list->blockSignals(old_signal_state);
00117 }
00118
00119 void MainWindow::trajectorySelectionChanged(void)
00120 {
00121 for (unsigned int i = 0; i < ui_.trajectory_list->count() ; ++i)
00122 {
00123 QListWidgetItem *item = ui_.trajectory_list->item(i);
00124 std::string name = item->text().toStdString();
00125 if ( trajectories_.find(name) != trajectories_.end() && item->isSelected())
00126 {
00127 trajectories_[name]->show(scene_display_->getSceneNode(), visualization_manager_);
00128 }
00129 else
00130 {
00131 trajectories_[name]->hide();
00132 }
00133 }
00134 }
00135
00136 void MainWindow::removeTrajectoryButtonClicked(void)
00137 {
00138 if (ui_.trajectory_list->currentItem())
00139 {
00140
00141 QMessageBox msgBox;
00142 msgBox.setText("The selected trajectory will be removed from the database");
00143 msgBox.setInformativeText("Do you want to continue?");
00144 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
00145 msgBox.setDefaultButton(QMessageBox::No);
00146 int ret = msgBox.exec();
00147
00148 switch (ret)
00149 {
00150 case QMessageBox::Yes:
00151 {
00152
00153 QList<QListWidgetItem*> found_items = ui_.trajectory_list->selectedItems();
00154 for ( std::size_t i = 0 ; i < found_items.size() ; i++ )
00155 {
00156 try
00157 {
00158 trajectory_constraints_storage_->removeTrajectoryConstraints(found_items[i]->text().toStdString());
00159 }
00160 catch (std::runtime_error &ex)
00161 {
00162 ROS_ERROR("%s", ex.what());
00163 }
00164 trajectories_.erase(found_items[i]->text().toStdString());
00165 }
00166 populateTrajectoriesList();
00167 }
00168 break;
00169 }
00170 }
00171 }
00172
00173 void MainWindow::loadTrajectoriesFromDBButtonClicked(void)
00174 {
00175
00176 if (trajectory_constraints_storage_ && !robot_interaction_->getActiveEndEffectors().empty())
00177 {
00178
00179 trajectories_.clear();
00180
00181 std::vector<std::string> names;
00182 try
00183 {
00184 trajectory_constraints_storage_->getKnownTrajectoryConstraints(ui_.trajectories_filter_text->text().toStdString(), names);
00185 }
00186 catch (std::runtime_error &ex)
00187 {
00188 QMessageBox::warning(this, "Cannot query the database", QString("Wrongly formatted regular expression for trajectory contraints: ").append(ex.what()));
00189 return;
00190 }
00191
00192 for (unsigned int i = 0 ; i < names.size() ; i++)
00193 {
00194
00195 moveit_warehouse::TrajectoryConstraintsWithMetadata tc;
00196 bool got_constraint = false;
00197 try
00198 {
00199 got_constraint = trajectory_constraints_storage_->getTrajectoryConstraints(tc, names[i]);
00200 }
00201 catch (std::runtime_error &ex)
00202 {
00203 ROS_ERROR("%s", ex.what());
00204 }
00205 if (!got_constraint)
00206 continue;
00207
00208 if (tc->constraints.size() > 0 && tc->constraints[0].position_constraints[0].constraint_region.primitive_poses.size() > 0 && tc->constraints[0].orientation_constraints.size() > 0)
00209 {
00210 geometry_msgs::Pose shape_pose;
00211 shape_pose.position = tc->constraints[0].position_constraints[0].constraint_region.primitive_poses[0].position;
00212 shape_pose.orientation = tc->constraints[0].orientation_constraints[0].orientation;
00213 static const float marker_scale = 0.15;
00214 TrajectoryPtr trajectory_marker( new Trajectory(scene_display_->getPlanningSceneRO()->getCurrentState(), scene_display_->getSceneNode(), visualization_manager_,
00215 names[i], scene_display_->getRobotModel()->getModelFrame(),
00216 robot_interaction_->getActiveEndEffectors()[0], shape_pose, marker_scale, GripperMarker::NOT_TESTED,
00217 ui_.trajectory_nwaypoints_spin->value()));
00218
00219 if ( trajectories_.find(names[i]) != trajectories_.end() )
00220 {
00221 trajectories_.erase(names[i]);
00222 }
00223 trajectories_.insert(TrajectoryPair(names[i], trajectory_marker));
00224
00225 for (std::size_t c = 0; c < tc->constraints.size(); ++c)
00226 {
00227 if (tc->constraints[c].position_constraints.size() > 0 && tc->constraints[c].position_constraints[0].constraint_region.primitive_poses.size() > 0 && tc->constraints[c].orientation_constraints.size() > 0 )
00228 {
00229 shape_pose.position = tc->constraints[c].position_constraints[0].constraint_region.primitive_poses[0].position;
00230 shape_pose.orientation = tc->constraints[c].orientation_constraints[0].orientation;
00231
00232 static const float marker_scale = 0.15;
00233 GripperMarkerPtr waypoint_marker( new GripperMarker(scene_display_->getPlanningSceneRO()->getCurrentState(), scene_display_->getSceneNode(), visualization_manager_,
00234 names[i], scene_display_->getRobotModel()->getModelFrame(),
00235 robot_interaction_->getActiveEndEffectors()[0], shape_pose, marker_scale, GripperMarker::NOT_TESTED));
00236 waypoint_marker->unselect(true);
00237 waypoint_marker->setColor(0.0, 0.9, 0.0, 1 - (double)c / (double)tc->constraints.size());
00238 trajectory_marker->waypoint_markers.push_back(waypoint_marker);
00239 }
00240 }
00241
00242 if (trajectory_marker->waypoint_markers.size() > 0)
00243 {
00244 trajectory_marker->start_marker = GripperMarkerPtr(new GripperMarker(*trajectory_marker->waypoint_markers.front()));
00245 trajectory_marker->end_marker = GripperMarkerPtr(new GripperMarker(*trajectory_marker->waypoint_markers.back()));
00246 trajectory_marker->waypoint_markers.front()->getPose(trajectory_marker->control_marker_start_pose);
00247 trajectory_marker->waypoint_markers.back()->getPose(trajectory_marker->control_marker_end_pose);
00248 }
00249 populateTrajectoriesList();
00250 selectFirstItemInList(ui_.trajectory_list);
00251 }
00252 }
00253 }
00254 else
00255 {
00256 if (!trajectory_constraints_storage_)
00257 QMessageBox::warning(this, "Warning", "Not connected to a database.");
00258 }
00259 }
00260
00261 void MainWindow::saveTrajectoriesOnDBButtonClicked(void)
00262 {
00263 if (trajectory_constraints_storage_)
00264 {
00265
00266 for (TrajectoryMap::iterator it = trajectories_.begin(); it != trajectories_.end(); ++it)
00267 {
00268 moveit_msgs::TrajectoryConstraints tc;
00269
00270 for (std::size_t w = 0; w < it->second->waypoint_markers.size(); ++w)
00271 {
00272 moveit_msgs::Constraints c;
00273 c.name = it->second->waypoint_markers[w]->getName();
00274
00275 shape_msgs::SolidPrimitive sp;
00276 sp.type = sp.BOX;
00277 sp.dimensions.resize(3, std::numeric_limits<float>::epsilon() * 10.0);
00278
00279 moveit_msgs::PositionConstraint pc;
00280 pc.constraint_region.primitives.push_back(sp);
00281 geometry_msgs::Pose posemsg;
00282 it->second->waypoint_markers[w]->getPosition(posemsg.position);
00283 posemsg.orientation.x = 0.0;
00284 posemsg.orientation.y = 0.0;
00285 posemsg.orientation.z = 0.0;
00286 posemsg.orientation.w = 1.0;
00287 pc.constraint_region.primitive_poses.push_back(posemsg);
00288 pc.weight = 1.0;
00289 c.position_constraints.push_back(pc);
00290
00291 moveit_msgs::OrientationConstraint oc;
00292 it->second->waypoint_markers[w]->getOrientation(oc.orientation);
00293 oc.absolute_x_axis_tolerance = oc.absolute_y_axis_tolerance =
00294 oc.absolute_z_axis_tolerance = std::numeric_limits<float>::epsilon() * 10.0;
00295 oc.weight = 1.0;
00296 c.orientation_constraints.push_back(oc);
00297 tc.constraints.push_back(c);
00298 }
00299
00300 try
00301 {
00302 trajectory_constraints_storage_->addTrajectoryConstraints(tc, it->first);
00303 }
00304 catch (std::runtime_error &ex)
00305 {
00306 ROS_ERROR("Cannot save trajectory constraint: %s", ex.what());
00307 }
00308 }
00309 }
00310 else
00311 {
00312 QMessageBox::warning(this, "Warning", "Not connected to a database.");
00313 }
00314 }
00315
00316 void MainWindow::trajectoryNWaypointsChanged(int n)
00317 {
00318 if (ui_.trajectory_list->currentItem())
00319 {
00320 TrajectoryMap::iterator it = trajectories_.find(ui_.trajectory_list->currentItem()->text().toStdString());
00321 it->second->setNumberOfWaypoints(n);
00322 }
00323 }
00324
00325 void MainWindow::trajectoryExecuteButtonClicked()
00326 {
00327 if (ui_.trajectory_list->currentItem())
00328 {
00329 TrajectoryMap::iterator it = trajectories_.find(ui_.trajectory_list->currentItem()->text().toStdString());
00330 EigenSTL::vector_Affine3d waypoint_poses;
00331 for (std::size_t w = 1; w < it->second->waypoint_markers.size(); ++w )
00332 {
00333 Eigen::Affine3d pose;
00334 it->second->waypoint_markers[w]->getPose(pose);
00335 waypoint_poses.push_back(pose);
00336 }
00337
00338 if (waypoint_poses.size() > 0)
00339 {
00340 robot_state::RobotState &rstate = scene_display_->getPlanningSceneRW()->getCurrentStateNonConst();
00341 rstate.update();
00342 const robot_model::JointModelGroup *jmg = rstate.getJointModelGroup(ui_.planning_group_combo->currentText().toStdString());
00343
00344 std::vector<robot_state::RobotStatePtr> traj;
00345 double completed = rstate.computeCartesianPath(jmg, traj, rstate.getLinkModel(robot_interaction_->getActiveEndEffectors()[0].parent_link),
00346 waypoint_poses, true, 0.04, 0.0);
00347
00348 ROS_INFO_STREAM("Trajectory completion percentage " << completed);
00349 JobProcessing::addBackgroundJob(boost::bind(&MainWindow::animateTrajectory, this, traj));
00350 }
00351 }
00352 }
00353
00354 void MainWindow::animateTrajectory(const std::vector<boost::shared_ptr<robot_state::RobotState> > &traj)
00355 {
00356 for (std::size_t i = 0; i < traj.size(); ++i)
00357 {
00358 scene_display_->getPlanningSceneRW()->setCurrentState(*traj[i]);
00359 scene_display_->queueRenderSceneGeometry();
00360 usleep(100000);
00361 }
00362 }
00363
00364 }