tab_trajectories.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2012, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 /* Author: Mario Prats, Ioan Sucan */
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         //Create the new trajectory starting point at the current eef pose, and attach an interactive marker to it
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     //Warn the user
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         //Go through the list of trajectories, and delete those selected
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   //Get all the trajectory constraints from the database
00176   if (trajectory_constraints_storage_ && !robot_interaction_->getActiveEndEffectors().empty())
00177   {
00178     //First clear the current list
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       //Create a trajectory constraint
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     //Convert all goal trajectory markers into constraints and store them
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 } // namespace


benchmarks_gui
Author(s): Mario Prats
autogenerated on Wed Aug 26 2015 12:44:27