default_collisions_widget.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 the 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: Dave Coleman */
00036 
00037 
00038 #include <QHBoxLayout>
00039 #include <QMessageBox>
00040 #include <QProgressDialog>
00041 #include <QString>
00042 #include <QFont>
00043 #include <QApplication>
00044 #include "default_collisions_widget.h"
00045 #include <boost/unordered_map.hpp>
00046 #include <boost/assign.hpp>
00047 #include <ros/console.h>
00048 
00049 namespace moveit_setup_assistant
00050 {
00051 
00053 const boost::unordered_map<moveit_setup_assistant::DisabledReason, const char*> longReasonsToString =
00054   boost::assign::map_list_of
00055   ( moveit_setup_assistant::NEVER, "Never in Collision" )
00056   ( moveit_setup_assistant::DEFAULT, "Collision by Default" )
00057   ( moveit_setup_assistant::ADJACENT, "Adjacent Links" )
00058   ( moveit_setup_assistant::ALWAYS, "Always in Collision" )
00059   ( moveit_setup_assistant::USER, "User Disabled" )
00060   ( moveit_setup_assistant::NOT_DISABLED, "");
00061 
00065 class CheckboxSortWidgetItem : public QTableWidgetItem {
00066 public:
00070   bool operator <(const QTableWidgetItem &other) const
00071   {
00072     return checkState() < other.checkState();
00073   }
00074 };
00075 
00076 // ******************************************************************************************
00077 // User interface for editing the default collision matrix list in an SRDF
00078 // ******************************************************************************************
00079 DefaultCollisionsWidget::DefaultCollisionsWidget( QWidget *parent,
00080                                                   MoveItConfigDataPtr config_data )
00081   : SetupScreenWidget( parent ), config_data_(config_data)
00082 {
00083   // Basic widget container
00084   layout_ = new QVBoxLayout( this );
00085 
00086   // Top Label Area ------------------------------------------------
00087   HeaderWidget *header = new HeaderWidget( "Optimize Self-Collision Checking",
00088                                            "The Default Self-Collision Matrix Generator will search for pairs of links on the robot that can safely be disabled from collision checking, decreasing motion planning processing time. These pairs of links are disabled when they are always in collision, never in collision, in collision in the robot's default position or when the links are adjacent to each other on the kinematic chain. Sampling density specifies how many random robot positions to check for self collision. Higher densities require more computation time.",
00089                                            this);
00090   layout_->addWidget( header );
00091 
00092   // Top Button Area -----------------------------------------------
00093   controls_box_ = new QGroupBox( this );
00094   layout_->addWidget( controls_box_ );
00095   QHBoxLayout *controls_box_layout = new QHBoxLayout( controls_box_ );
00096   controls_box_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00097 
00098   // Slider Label
00099   QLabel *density_left_label = new QLabel( this );
00100   density_left_label->setText("Sampling Density: Low");
00101   controls_box_layout->addWidget(density_left_label);
00102 
00103   // Slider
00104   density_slider_ = new QSlider( this );
00105   density_slider_->setTickPosition(QSlider::TicksBelow);
00106   density_slider_->setMinimum( 0 );
00107   density_slider_->setMaximum( 99 );
00108   density_slider_->setSingleStep( 10 );
00109   density_slider_->setPageStep( 50 );
00110   density_slider_->setSliderPosition( 9 ); // 10,000 is default
00111   density_slider_->setTickInterval( 10 );
00112   density_slider_->setOrientation( Qt::Horizontal );
00113   controls_box_layout->addWidget(density_slider_);
00114   connect(density_slider_, SIGNAL(valueChanged(int)), this, SLOT(changeDensityLabel(int)));
00115 
00116   // Slider Right Label
00117   QLabel *density_right_label = new QLabel( this );
00118   density_right_label->setText("High   ");
00119   controls_box_layout->addWidget(density_right_label);
00120 
00121   // Slider Value Label
00122   density_value_label_ = new QLabel( this );
00123   density_value_label_->setMinimumWidth(50);
00124   controls_box_layout->addWidget(density_value_label_);
00125   changeDensityLabel( density_slider_->value() ); // initialize label with value
00126 
00127 
00128   // Generate Button
00129   btn_generate_ = new QPushButton( this );
00130   btn_generate_->setText("&Generate Collision Matrix");
00131   btn_generate_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred );
00132   connect(btn_generate_, SIGNAL(clicked()), this, SLOT(generateCollisionTable()));
00133   layout_->addWidget(btn_generate_);
00134   layout_->setAlignment( btn_generate_, Qt::AlignRight );
00135 
00136   // Progress Bar Area ---------------------------------------------
00137 
00138   // Progress Label
00139   progress_label_ = new QLabel( this );
00140   progress_label_->setText("Generating Default Collision Matrix");
00141   progress_label_->hide();
00142   layout_->addWidget(progress_label_);
00143 
00144   // Progress Bar
00145   progress_bar_ = new QProgressBar( this );
00146   progress_bar_->setMaximum(100);
00147   progress_bar_->setMinimum(0);
00148   progress_bar_->hide(); // only show when computation begins
00149   layout_->addWidget(progress_bar_); //,Qt::AlignCenter);
00150 
00151   // Table Area --------------------------------------------
00152 
00153   // Table
00154   collision_table_ = new QTableWidget( this );
00155   collision_table_->setColumnCount(4);
00156   collision_table_->setSortingEnabled(true);
00157   collision_table_->setSelectionBehavior( QAbstractItemView::SelectRows );
00158   connect( collision_table_, SIGNAL( cellClicked( int, int ) ), this, SLOT( previewClicked( int, int ) ) );
00159   layout_->addWidget(collision_table_);
00160 
00161   QStringList header_list;
00162   header_list.append("Link A");
00163   header_list.append("Link B");
00164   header_list.append("Disabled");
00165   header_list.append("Reason To Disable");
00166   collision_table_->setHorizontalHeaderLabels(header_list);
00167 
00168   // Resize headers
00169   collision_table_->resizeColumnToContents(0);
00170   collision_table_->resizeColumnToContents(1);
00171   collision_table_->resizeColumnToContents(2);
00172   collision_table_->resizeColumnToContents(3);
00173 
00174   // Bottom Area ----------------------------------------
00175   controls_box_bottom_ = new QGroupBox( this );
00176   layout_->addWidget( controls_box_bottom_ );
00177   QHBoxLayout *controls_box_bottom_layout = new QHBoxLayout( controls_box_bottom_ );
00178 
00179   // Checkbox
00180   collision_checkbox_ = new QCheckBox( this );
00181   collision_checkbox_->setText("Show Non-Disabled Link Pairs");
00182   connect(collision_checkbox_, SIGNAL(toggled(bool)), this, SLOT(collisionCheckboxToggle()));
00183   controls_box_bottom_layout->addWidget(collision_checkbox_);
00184 
00185   fraction_label_ = new QLabel(this);
00186   fraction_label_->setText("Min. collisions for \"always\"-colliding pairs:");
00187 
00188   controls_box_bottom_layout->addWidget(fraction_label_);
00189 
00190   fraction_spinbox_ = new QSpinBox(this);
00191   fraction_spinbox_->setRange(1, 100);
00192   fraction_spinbox_->setValue(95);
00193   fraction_spinbox_->setSuffix("%");
00194   controls_box_bottom_layout->addWidget(fraction_spinbox_);
00195 
00196   controls_box_bottom_layout->setAlignment(collision_checkbox_, Qt::AlignLeft);
00197 
00198   setLayout(layout_);
00199 
00200   setWindowTitle("Default Collision Matrix");
00201 }
00202 
00203 // ******************************************************************************************
00204 // Qt close event function for reminding user to save
00205 // ******************************************************************************************
00206 void DefaultCollisionsWidget::generateCollisionTable()
00207 {
00208   // Confirm the user wants to overwrite the current disabled collisions
00209   if( !config_data_->srdf_->disabled_collisions_.empty() )
00210   {
00211     if( QMessageBox::question( this, "Confirm Disabled Collision Overwrite",
00212                                "Are you sure you want to overwrite the current default collisions matrix with a newly generated one?",
00213                                QMessageBox::Ok | QMessageBox::Cancel)
00214         == QMessageBox::Cancel )
00215     {
00216       return; // abort
00217     }
00218   }
00219   QApplication::processEvents(); // allow the progress bar to be shown
00220   progress_label_->setText("Computing default collision matrix for robot model...");
00221 
00222   // Disable controls on form
00223   disableControls(true);
00224 
00225   // Create a progress variable that will be shared with the compute_default_collisions tool and its threads
00226   // NOTE: be sure not to delete this variable until the subprograms have finished using it. Because of the simple
00227   // use case of this variable (1 thread writes to it, the parent process reads it) it was decided a boost shared
00228   // pointer is not necessary.
00229   unsigned int collision_progress = 0;
00230   progress_bar_->setValue(collision_progress);
00231 
00232   QApplication::processEvents(); // allow the progress bar to be shown
00233 
00234   // Create thread to do actual work
00235   boost::thread workerThread( boost::bind( &DefaultCollisionsWidget::generateCollisionTableThread,
00236                                            this, &collision_progress ));
00237   // Check interval
00238   boost::posix_time::seconds check_interval(1);
00239 
00240   // Continually loop until threaded computation is finished
00241   while( collision_progress < 100 )
00242   {
00243     // Set updated progress value.
00244     progress_bar_->setValue(collision_progress);
00245 
00246     // Allow GUI thread to do its stuff
00247     QApplication::processEvents();
00248 
00249     // 1 second sleep
00250     boost::this_thread::sleep(check_interval);
00251     //usleep(1000 * 1000);
00252   }
00253 
00254   // Wait for thread to finish
00255   workerThread.join();
00256 
00257   // Load the results into the GUI
00258   loadCollisionTable();
00259 
00260   // Hide the progress bar
00261   disableControls(false); // enable everything else
00262 }
00263 
00264 // ******************************************************************************************
00265 // The thread that is called to allow the GUI to update. Calls an external function to do calcs
00266 // ******************************************************************************************
00267 void DefaultCollisionsWidget::generateCollisionTableThread( unsigned int *collision_progress )
00268 {
00269   unsigned int num_trials = density_slider_->value() * 1000 + 1000; // scale to trials amount
00270   double min_frac = (double)fraction_spinbox_->value() / 100.0;
00271 
00272   const bool verbose = true; // Output benchmarking and statistics
00273   const bool include_never_colliding = true;
00274 
00275   // clear previously loaded collision matrix entries
00276   config_data_->getPlanningScene()->getAllowedCollisionMatrixNonConst().clear();
00277 
00278   // Find the default collision matrix - all links that are allowed to collide
00279   link_pairs_ =
00280     moveit_setup_assistant::computeDefaultCollisions( config_data_->getPlanningScene(),
00281                                                       collision_progress, include_never_colliding, num_trials,
00282                                                       min_frac, verbose);
00283 
00284   // Copy data changes to srdf_writer object
00285   linkPairsToSRDF();
00286 
00287   // End the progress bar loop
00288   *collision_progress = 100;
00289 
00290   ROS_INFO_STREAM("Thread complete " << link_pairs_.size());
00291 }
00292 
00293 // ******************************************************************************************
00294 // Displays data in the link_pairs_ data structure into a QtTableWidget
00295 // ******************************************************************************************
00296 void DefaultCollisionsWidget::loadCollisionTable()
00297 {
00298   int row = 0;
00299   int progress_counter = 0;
00300 
00301   // Show Progress Bar
00302   progress_bar_->setValue(0);
00303 
00304   QApplication::processEvents(); // allow the progress bar to be shown
00305   progress_label_->setText("Loading table...");
00306 
00307   // Setup Collision Table
00308   collision_table_->setUpdatesEnabled(false); // prevent table from updating until we are completely done
00309   collision_table_->setDisabled(true); // make sure we disable it so that the cellChanged event is not called
00310   collision_table_->clearContents();
00311 
00312   // Check if there are no disabled collisions (unprobable?)
00313   if(link_pairs_.empty())
00314   {
00315     collision_table_->setRowCount(1);
00316     QTableWidgetItem* no_collide = new QTableWidgetItem("No Link Pairs Of This Kind");
00317     collision_table_->setItem(0, 0, no_collide);
00318   }
00319   else
00320   {
00321     // The table will be populated, so indicate it on the button
00322     btn_generate_->setText("Regenerate Default Collision Matrix");
00323   }
00324 
00325 
00326   // Intially set the table to be worst-case scenario of every possible element pair
00327   collision_table_->setRowCount( link_pairs_.size() );
00328 
00329   for ( moveit_setup_assistant::LinkPairMap::const_iterator pair_it = link_pairs_.begin();
00330         pair_it != link_pairs_.end();
00331         ++pair_it)
00332   {
00333     // Add link pair row if 1) it is disabled from collision checking or 2) the SHOW ALL LINK PAIRS checkbox is checked
00334     if( pair_it->second.disable_check || collision_checkbox_->isChecked() )
00335     {
00336 
00337       // Create row elements
00338       QTableWidgetItem* linkA = new QTableWidgetItem( pair_it->first.first.c_str() );
00339       linkA->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
00340 
00341       QTableWidgetItem* linkB = new QTableWidgetItem( pair_it->first.second.c_str() );
00342       linkB->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
00343 
00344       CheckboxSortWidgetItem* disable_check = new CheckboxSortWidgetItem( );
00345       disable_check->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
00346       if( pair_it->second.disable_check ) // Checked means no collision checking
00347         disable_check->setCheckState(Qt::Checked);
00348       else
00349         disable_check->setCheckState(Qt::Unchecked);
00350 
00351       QTableWidgetItem* reason = new QTableWidgetItem( longReasonsToString.at( pair_it->second.reason ) );
00352       reason->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
00353 
00354       // Insert row elements into collision table
00355       collision_table_->setItem( row, 0, linkA);
00356       collision_table_->setItem( row, 1, linkB);
00357       collision_table_->setItem( row, 2, disable_check);
00358       collision_table_->setItem( row, 3, reason);
00359 
00360       // Increment row count
00361       ++row;
00362     }
00363 
00364     ++progress_counter; // for calculating progress bar
00365 
00366     if( progress_counter % 200 == 0 )
00367     {
00368       // Update Progress Bar
00369       progress_bar_->setValue( progress_counter * 100 / link_pairs_.size() );
00370       QApplication::processEvents(); // allow the progress bar to be shown
00371     }
00372 
00373   }
00374 
00375   // Reduce the table size to only the number of used rows.
00376   collision_table_->setRowCount( row );
00377 
00378   // Resize headers. The hiding is a hack so that it resizes correctly
00379   collision_table_->setVisible(false);
00380   collision_table_->resizeColumnToContents(0);
00381   collision_table_->resizeColumnToContents(1);
00382   collision_table_->resizeColumnToContents(2);
00383   collision_table_->resizeColumnToContents(3);
00384   collision_table_->setVisible(true);
00385 
00386   collision_table_->setUpdatesEnabled(true); // prevent table from updating until we are completely done
00387 }
00388 
00389 // ******************************************************************************************
00390 // GUI func for showing sampling density amount
00391 // ******************************************************************************************
00392 void DefaultCollisionsWidget::changeDensityLabel(int value)
00393 {
00394   density_value_label_->setText( QString::number( value*1000 + 1000) ); //.append(" samples") );
00395 }
00396 
00397 // ******************************************************************************************
00398 // Helper function to disable parts of GUI during computation
00399 // ******************************************************************************************
00400 void DefaultCollisionsWidget::disableControls(bool disable)
00401 {
00402   controls_box_->setDisabled( disable );
00403   collision_table_->setDisabled( disable );
00404   collision_checkbox_->setDisabled( disable );
00405 
00406   if( disable )
00407   {
00408     progress_bar_->show(); // only show when computation begins
00409     progress_label_->show();
00410   }
00411   else
00412   {
00413     progress_label_->hide();
00414     progress_bar_->hide();
00415   }
00416 
00417   QApplication::processEvents(); // allow the progress bar to be shown
00418 }
00419 
00420 // ******************************************************************************************
00421 // Changes the table to show or hide collisions that are not disabled (that have collision checking enabled)
00422 // ******************************************************************************************
00423 void DefaultCollisionsWidget::collisionCheckboxToggle()
00424 {
00425   // Show Progress bar
00426   disableControls( true );
00427 
00428   // Now update collision table with updates
00429   loadCollisionTable();
00430 
00431   // Hide Progress bar
00432   disableControls( false );
00433 }
00434 
00435 // ******************************************************************************************
00436 // Called when user changes data in table, really just the checkbox
00437 // ******************************************************************************************
00438 void DefaultCollisionsWidget::toggleCheckBox(int j, int i) // these are flipped on purpose
00439 {
00440   // Only accept cell changes if table is enabled, otherwise it is this program making changes
00441   if( collision_table_->isEnabled() )
00442   {
00443     // Make sure change is the checkbox column
00444     if( i == 2 )
00445     {
00446 
00447       // Convert row to pair
00448       std::pair<std::string, std::string> link_pair;
00449       link_pair.first = collision_table_->item(j, 0)->text().toStdString();
00450       link_pair.second = collision_table_->item(j, 1)->text().toStdString();
00451 
00452       // Get the state of checkbox
00453       bool check_state = collision_table_->item(j, 2)->checkState();
00454 
00455 
00456       // Check if the checkbox state has changed from original value
00457       if( link_pairs_[ link_pair ].disable_check != check_state )
00458       {
00459 
00460         // Save the change
00461         link_pairs_[ link_pair ].disable_check = check_state;
00462 
00463         // Handle USER Reasons: 1) pair is disabled by user
00464         if( link_pairs_[ link_pair ].disable_check == true &&
00465             link_pairs_[ link_pair ].reason == moveit_setup_assistant::NOT_DISABLED )
00466         {
00467           link_pairs_[ link_pair ].reason = moveit_setup_assistant::USER;
00468 
00469           // Change Reason in Table
00470           collision_table_->item(j, 3)->setText( longReasonsToString.at( link_pairs_[ link_pair ].reason ) );
00471         }
00472         // Handle USER Reasons: 2) pair was disabled by user and now is enabled (not checked)
00473         else if( link_pairs_[ link_pair ].disable_check == false &&
00474                  link_pairs_[ link_pair ].reason == moveit_setup_assistant::USER )
00475         {
00476           link_pairs_[ link_pair ].reason = moveit_setup_assistant::NOT_DISABLED;
00477 
00478           // Change Reason in Table
00479           collision_table_->item(j, 3)->setText( "" );
00480         }
00481 
00482       }
00483 
00484       // Copy data changes to srdf_writer object
00485       linkPairsToSRDF();
00486     }
00487   }
00488 }
00489 
00490 // ******************************************************************************************
00491 // Output Link Pairs to SRDF Format and update the collision matrix
00492 // ******************************************************************************************
00493 void DefaultCollisionsWidget::linkPairsToSRDF()
00494 {
00495   // reset the data in the SRDF Writer class
00496   config_data_->srdf_->disabled_collisions_.clear();
00497 
00498   // Create temp disabled collision
00499   srdf::Model::DisabledCollision dc;
00500 
00501   // copy the data in this class's LinkPairMap datastructure to srdf::Model::DisabledCollision format
00502   for ( moveit_setup_assistant::LinkPairMap::const_iterator pair_it = link_pairs_.begin();
00503         pair_it != link_pairs_.end(); ++pair_it)
00504   {
00505     // Only copy those that are actually disabled
00506     if( pair_it->second.disable_check )
00507     {
00508       dc.link1_ = pair_it->first.first;
00509       dc.link2_ = pair_it->first.second;
00510       dc.reason_ = moveit_setup_assistant::disabledReasonToString( pair_it->second.reason );
00511       config_data_->srdf_->disabled_collisions_.push_back( dc );
00512     }
00513   }
00514 
00515   // Update collision_matrix for robot pose's use
00516   config_data_->loadAllowedCollisionMatrix();
00517 
00518 }
00519 
00520 // ******************************************************************************************
00521 // Load Link Pairs from SRDF Format
00522 // ******************************************************************************************
00523 void DefaultCollisionsWidget::linkPairsFromSRDF()
00524 {
00525   // Clear all the previous data in the compute_default_collisions tool
00526   link_pairs_.clear();
00527 
00528   // Create new instance of planning scene using pointer
00529   planning_scene::PlanningScenePtr scene = config_data_->getPlanningScene()->diff();
00530 
00531   // Populate link_pairs_ list with every possible n choose 2 combination of links
00532   moveit_setup_assistant::computeLinkPairs(*scene, link_pairs_);
00533 
00534   // Create temp link pair data struct
00535   moveit_setup_assistant::LinkPairData link_pair_data;
00536   std::pair<std::string, std::string> link_pair;
00537 
00538   // Loop through all disabled collisions in SRDF and update the comprehensive list that has already been created
00539   for( std::vector<srdf::Model::DisabledCollision>::const_iterator collision_it =
00540          config_data_->srdf_->disabled_collisions_.begin();
00541        collision_it != config_data_->srdf_->disabled_collisions_.end(); ++collision_it )
00542   {
00543     // Set the link names
00544     link_pair.first = collision_it->link1_;
00545     link_pair.second = collision_it->link2_;
00546 
00547     // Set the link meta data
00548     link_pair_data.reason = moveit_setup_assistant::disabledReasonFromString( collision_it->reason_ );
00549     link_pair_data.disable_check = true; // disable checking the collision btw the 2 links
00550 
00551     // Insert into map
00552     link_pairs_[ link_pair ] = link_pair_data;
00553   }
00554 }
00555 
00556 // ******************************************************************************************
00557 // Preview whatever element is selected
00558 // ******************************************************************************************
00559 void DefaultCollisionsWidget::previewClicked( int row, int column )
00560 {
00561   // Get list of all selected items
00562   QList<QTableWidgetItem*> selected = collision_table_->selectedItems();
00563 
00564   // Check that an element was selected
00565   if( !selected.size() )
00566     return;
00567 
00568   // Unhighlight all links
00569   Q_EMIT unhighlightAll();
00570 
00571   // Highlight link
00572   Q_EMIT highlightLink( selected[0]->text().toStdString() );
00573   Q_EMIT highlightLink( selected[1]->text().toStdString() );
00574 }
00575 
00576 // ******************************************************************************************
00577 // Called when setup assistant navigation switches to this screen
00578 // ******************************************************************************************
00579 void DefaultCollisionsWidget::focusGiven()
00580 {
00581   // Convert the SRDF data to LinkPairData format
00582   linkPairsFromSRDF();
00583 
00584   // Load the data to the table
00585   loadCollisionTable();
00586 
00587   // Enable the table
00588   disableControls( false );
00589 }
00590 
00591 
00592 } // namespace


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Mon Oct 6 2014 02:32:27