kinematic_chain_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 #include <QVBoxLayout>
00038 #include <QHBoxLayout>
00039 #include <QGroupBox>
00040 #include <QPushButton>
00041 #include <QGridLayout>
00042 #include <QLineEdit>
00043 #include <QMessageBox>
00044 #include <QString>
00045 #include "kinematic_chain_widget.h"
00046 
00047 namespace moveit_setup_assistant
00048 {
00049 
00050 // ******************************************************************************************
00051 // Constructor
00052 // ******************************************************************************************
00053 KinematicChainWidget::KinematicChainWidget( QWidget *parent, moveit_setup_assistant::MoveItConfigDataPtr config_data )
00054   :  QWidget( parent ), config_data_( config_data )
00055 {
00056   // Basic widget container
00057   QVBoxLayout *layout = new QVBoxLayout( );
00058 
00059   // Label ------------------------------------------------
00060   title_ = new QLabel( "", this ); // specify the title from the parent widget
00061   QFont group_title_font( "Arial", 12, QFont::Bold );
00062   title_->setFont(group_title_font);
00063   layout->addWidget( title_ );
00064 
00065   // Create link tree ------------------------------------------------------
00066   link_tree_ = new QTreeWidget( this );
00067   link_tree_->setHeaderLabel( "Robot Links" );
00068   connect( link_tree_, SIGNAL( itemSelectionChanged() ), this, SLOT( itemSelected() ) );
00069   layout->addWidget( link_tree_ );
00070 
00071   // Create Grid Layout for form --------------------------------------------
00072   QGridLayout *form_grid = new QGridLayout();
00073   form_grid->setContentsMargins( 20, 20, 20, 20 ); // left top right bottom
00074 
00075   // Row 1: Base Link
00076   QLabel *base_link_label = new QLabel( "Base Link", this );
00077   form_grid->addWidget( base_link_label, 0, 0, Qt::AlignRight );
00078 
00079   base_link_field_ = new QLineEdit( this );
00080   base_link_field_->setMinimumWidth( 300 );
00081   form_grid->addWidget( base_link_field_, 0, 1, Qt::AlignLeft );
00082 
00083   QPushButton *btn_base_link = new QPushButton( "Choose Selected", this );
00084   connect( btn_base_link, SIGNAL( clicked() ), this, SLOT( baseLinkTreeClick() ));
00085   form_grid->addWidget( btn_base_link, 0, 2, Qt::AlignLeft );
00086 
00087   // Row 2: Tip Link
00088   QLabel *tip_link_label = new QLabel( "Tip Link", this );
00089   form_grid->addWidget( tip_link_label, 1, 0, Qt::AlignRight );
00090 
00091   tip_link_field_ = new QLineEdit( this );
00092   tip_link_field_->setMinimumWidth( 300 );
00093   form_grid->addWidget( tip_link_field_, 1, 1, Qt::AlignLeft );
00094 
00095   QPushButton *btn_tip_link = new QPushButton( "Choose Selected", this );
00096   connect( btn_tip_link, SIGNAL( clicked() ), this, SLOT( tipLinkTreeClick() ));
00097   form_grid->addWidget( btn_tip_link, 1, 2, Qt::AlignLeft );
00098 
00099   // Add form grid layout
00100   layout->addLayout( form_grid );
00101 
00102   // Bottom Controls ---------------------------------------------------------
00103   QHBoxLayout *controls_layout = new QHBoxLayout();
00104 
00105   // Expand/Contract controls
00106   QLabel *expand_controls = new QLabel( this );
00107   expand_controls->setText("<a href='expand'>Expand All</a> <a href='contract'>Collapse All</a>");
00108   connect( expand_controls, SIGNAL(linkActivated( const QString )), this, SLOT( alterTree( const QString )));
00109   controls_layout->addWidget( expand_controls );
00110 
00111   // Spacer
00112   QWidget *spacer = new QWidget( this );
00113   spacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
00114   controls_layout->addWidget( spacer );
00115 
00116   // Save
00117   QPushButton *btn_save = new QPushButton( "&Save", this );
00118   btn_save->setMaximumWidth( 200 );
00119   connect( btn_save, SIGNAL(clicked()), this, SIGNAL( doneEditing() ) );
00120   controls_layout->addWidget( btn_save );
00121   controls_layout->setAlignment(btn_save, Qt::AlignRight);
00122 
00123   // Cancel
00124   QPushButton *btn_cancel = new QPushButton( "&Cancel", this );
00125   btn_cancel->setMaximumWidth( 200 );
00126   connect( btn_cancel, SIGNAL(clicked()), this, SIGNAL( cancelEditing() ) );
00127   controls_layout->addWidget( btn_cancel );
00128   controls_layout->setAlignment(btn_cancel, Qt::AlignRight);
00129 
00130   // Add layout
00131   layout->addLayout( controls_layout );
00132 
00133   // Finish Layout --------------------------------------------------
00134   this->setLayout(layout);
00135 
00136   // Remember that we have no loaded the chains yet
00137   kinematic_chain_loaded_ = false;
00138 }
00139 
00140 // ******************************************************************************************
00141 // Load robot links into tree
00142 // ******************************************************************************************
00143 void KinematicChainWidget::setAvailable()
00144 {
00145   // Only load the kinematic chain once
00146   if( kinematic_chain_loaded_ )
00147     return;
00148 
00149   // Retrieve pointer to the shared kinematic model
00150   const robot_model::RobotModelConstPtr &model = config_data_->getRobotModel();
00151 
00152   // Get the root joint
00153   const robot_model::JointModel *root_joint = model->getRoot();
00154 
00155   addLinktoTreeRecursive( root_joint->getChildLinkModel(), NULL);
00156 
00157   // Remember that we have loaded the chain
00158   kinematic_chain_loaded_ = true;
00159 }
00160 
00161 // ******************************************************************************************
00162 //
00163 // ******************************************************************************************
00164 void KinematicChainWidget::addLinktoTreeRecursive(const robot_model::LinkModel* link,
00165                                                   const robot_model::LinkModel* parent)
00166 {
00167   // Create new tree item
00168   QTreeWidgetItem* new_item = new QTreeWidgetItem(link_tree_);
00169 
00170   // Add item to tree
00171   if(parent == NULL)
00172   {
00173     new_item->setText(0, link->getName().c_str());
00174     link_tree_->addTopLevelItem(new_item);
00175   }
00176   else
00177   {
00178     for(int i = 0; i < link_tree_->topLevelItemCount(); i++)
00179     {
00180       if(addLinkChildRecursive(link_tree_->topLevelItem(i), link, parent->getName()))
00181       {
00182         break;
00183       }
00184     }
00185   }
00186   for(size_t i = 0; i < link->getChildJointModels().size(); i++)
00187   {
00188     addLinktoTreeRecursive(link->getChildJointModels()[i]->getChildLinkModel(), link);
00189   }
00190 }
00191 
00192 // ******************************************************************************************
00193 //
00194 // ******************************************************************************************
00195 bool KinematicChainWidget::addLinkChildRecursive(QTreeWidgetItem* parent,
00196                                                  const robot_model::LinkModel* link,
00197                                                  const std::string& parent_name)
00198 {
00199   if(parent->text(0).toStdString() == parent_name)
00200   {
00201     QTreeWidgetItem* new_item = new QTreeWidgetItem(parent);
00202     new_item->setText(0, link->getName().c_str());
00203 
00204     parent->addChild(new_item);
00205     return true;
00206   }
00207   else
00208   {
00209     for(int i = 0; i < parent->childCount(); i++)
00210     {
00211       if(addLinkChildRecursive(parent->child(i), link, parent_name))
00212       {
00213         return true;
00214       }
00215     }
00216   }
00217 
00218   return false;
00219 }
00220 
00221 // ******************************************************************************************
00222 // Set the link field with previous value
00223 // ******************************************************************************************
00224 void KinematicChainWidget::setSelected( const std::string &base_link, const std::string &tip_link )
00225 {
00226   base_link_field_->setText( QString( base_link.c_str() ) );
00227   tip_link_field_->setText( QString( tip_link.c_str() ) );
00228 }
00229 
00230 // ******************************************************************************************
00231 // Choose the base link
00232 // ******************************************************************************************
00233 void KinematicChainWidget::baseLinkTreeClick() {
00234   QTreeWidgetItem* item = link_tree_->currentItem();
00235   if(item != NULL)
00236   {
00237     base_link_field_->setText(item->text(0));
00238   }
00239 }
00240 
00241 // ******************************************************************************************
00242 // Choose the tip link
00243 // ******************************************************************************************
00244 void KinematicChainWidget::tipLinkTreeClick()
00245 {
00246   QTreeWidgetItem* item = link_tree_->currentItem();
00247   if(item != NULL)
00248   {
00249     tip_link_field_->setText(item->text(0));
00250   }
00251 }
00252 
00253 // ******************************************************************************************
00254 // Expand/Collapse Tree
00255 // ******************************************************************************************
00256 void KinematicChainWidget::alterTree( const QString &link )
00257 {
00258   if( link.contains("expand") )
00259     link_tree_->expandAll();
00260   else
00261     link_tree_->collapseAll();
00262 }
00263 
00264 // ******************************************************************************************
00265 // Highlight the currently selected link
00266 // ******************************************************************************************
00267 void KinematicChainWidget::itemSelected()
00268 {
00269   QTreeWidgetItem* item = link_tree_->currentItem();
00270   if(item != NULL)
00271   {
00272     Q_EMIT unhighlightAll();
00273 
00274     std::string name = item->text(0).toStdString();
00275 
00276     // Don't try to highlight empty links!
00277     if( name.empty() )
00278       return;
00279 
00280     // Check that item is not empty
00281     Q_EMIT highlightLink( item->text(0).toStdString() );
00282   }
00283 }
00284 
00285 }


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