kinematic_chain_widget.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Dave Coleman */
36 
37 #include <QVBoxLayout>
38 #include <QHBoxLayout>
39 #include <QGroupBox>
40 #include <QPushButton>
41 #include <QGridLayout>
42 #include <QLineEdit>
43 #include <QMessageBox>
44 #include <QLabel>
45 #include <QTreeWidget>
46 #include "kinematic_chain_widget.h"
47 
48 namespace moveit_setup_assistant
49 {
50 // ******************************************************************************************
51 // Constructor
52 // ******************************************************************************************
53 KinematicChainWidget::KinematicChainWidget(QWidget* parent, const MoveItConfigDataPtr& config_data)
54  : QWidget(parent), config_data_(config_data)
55 {
56  // Basic widget container
57  QVBoxLayout* layout = new QVBoxLayout();
58 
59  // Label ------------------------------------------------
60  title_ = new QLabel("", this); // specify the title from the parent widget
61  QFont group_title_font(QFont().defaultFamily(), 12, QFont::Bold);
62  title_->setFont(group_title_font);
63  layout->addWidget(title_);
64 
65  // Create link tree ------------------------------------------------------
66  link_tree_ = new QTreeWidget(this);
67  link_tree_->setHeaderLabel("Robot Links");
68  connect(link_tree_, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelected()));
69  layout->addWidget(link_tree_);
70 
71  // Create Grid Layout for form --------------------------------------------
72  QGridLayout* form_grid = new QGridLayout();
73  form_grid->setContentsMargins(20, 20, 20, 20); // left top right bottom
74 
75  // Row 1: Base Link
76  QLabel* base_link_label = new QLabel("Base Link", this);
77  form_grid->addWidget(base_link_label, 0, 0, Qt::AlignRight);
78 
79  base_link_field_ = new QLineEdit(this);
80  base_link_field_->setMinimumWidth(300);
81  form_grid->addWidget(base_link_field_, 0, 1, Qt::AlignLeft);
82 
83  QPushButton* btn_base_link = new QPushButton("Choose Selected", this);
84  connect(btn_base_link, SIGNAL(clicked()), this, SLOT(baseLinkTreeClick()));
85  form_grid->addWidget(btn_base_link, 0, 2, Qt::AlignLeft);
86 
87  // Row 2: Tip Link
88  QLabel* tip_link_label = new QLabel("Tip Link", this);
89  form_grid->addWidget(tip_link_label, 1, 0, Qt::AlignRight);
90 
91  tip_link_field_ = new QLineEdit(this);
92  tip_link_field_->setMinimumWidth(300);
93  form_grid->addWidget(tip_link_field_, 1, 1, Qt::AlignLeft);
94 
95  QPushButton* btn_tip_link = new QPushButton("Choose Selected", this);
96  connect(btn_tip_link, SIGNAL(clicked()), this, SLOT(tipLinkTreeClick()));
97  form_grid->addWidget(btn_tip_link, 1, 2, Qt::AlignLeft);
98 
99  // Add form grid layout
100  layout->addLayout(form_grid);
101 
102  // Bottom Controls ---------------------------------------------------------
103  QHBoxLayout* controls_layout = new QHBoxLayout();
104 
105  // Expand/Contract controls
106  QLabel* expand_controls = new QLabel(this);
107  expand_controls->setText("<a href='expand'>Expand All</a> <a href='contract'>Collapse All</a>");
108  connect(expand_controls, SIGNAL(linkActivated(const QString)), this, SLOT(alterTree(const QString)));
109  controls_layout->addWidget(expand_controls);
110 
111  // Spacer
112  controls_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
113 
114  // Save
115  QPushButton* btn_save = new QPushButton("&Save", this);
116  btn_save->setMaximumWidth(200);
117  connect(btn_save, SIGNAL(clicked()), this, SIGNAL(doneEditing()));
118  controls_layout->addWidget(btn_save);
119  controls_layout->setAlignment(btn_save, Qt::AlignRight);
120 
121  // Cancel
122  QPushButton* btn_cancel = new QPushButton("&Cancel", this);
123  btn_cancel->setMaximumWidth(200);
124  connect(btn_cancel, SIGNAL(clicked()), this, SIGNAL(cancelEditing()));
125  controls_layout->addWidget(btn_cancel);
126  controls_layout->setAlignment(btn_cancel, Qt::AlignRight);
127 
128  // Add layout
129  layout->addLayout(controls_layout);
130 
131  // Finish Layout --------------------------------------------------
132  this->setLayout(layout);
133 
134  // Remember that we have no loaded the chains yet
135  kinematic_chain_loaded_ = false;
136 }
137 
138 // ******************************************************************************************
139 // Load robot links into tree
140 // ******************************************************************************************
142 {
143  // Only load the kinematic chain once
145  return;
146 
147  // Retrieve pointer to the shared kinematic model
148  const moveit::core::RobotModelConstPtr& model = config_data_->getRobotModel();
149 
150  // Get the root joint
151  const moveit::core::JointModel* root_joint = model->getRootJoint();
152 
153  addLinktoTreeRecursive(root_joint->getChildLinkModel(), nullptr);
154 
155  // Remember that we have loaded the chain
157 }
158 
159 // ******************************************************************************************
160 //
161 // ******************************************************************************************
163  const moveit::core::LinkModel* parent)
164 {
165  // Create new tree item
166  QTreeWidgetItem* new_item = new QTreeWidgetItem(link_tree_);
167 
168  // Add item to tree
169  if (parent == nullptr)
170  {
171  new_item->setText(0, link->getName().c_str());
172  link_tree_->addTopLevelItem(new_item);
173  }
174  else
175  {
176  for (int i = 0; i < link_tree_->topLevelItemCount(); i++)
177  {
178  if (addLinkChildRecursive(link_tree_->topLevelItem(i), link, parent->getName()))
179  {
180  break;
181  }
182  }
183  }
184  for (std::size_t i = 0; i < link->getChildJointModels().size(); i++)
185  {
186  addLinktoTreeRecursive(link->getChildJointModels()[i]->getChildLinkModel(), link);
187  }
188 }
189 
190 // ******************************************************************************************
191 //
192 // ******************************************************************************************
193 bool KinematicChainWidget::addLinkChildRecursive(QTreeWidgetItem* parent, const moveit::core::LinkModel* link,
194  const std::string& parent_name)
195 {
196  if (parent->text(0).toStdString() == parent_name)
197  {
198  QTreeWidgetItem* new_item = new QTreeWidgetItem(parent);
199  new_item->setText(0, link->getName().c_str());
200 
201  parent->addChild(new_item);
202  return true;
203  }
204  else
205  {
206  for (int i = 0; i < parent->childCount(); i++)
207  {
208  if (addLinkChildRecursive(parent->child(i), link, parent_name))
209  {
210  return true;
211  }
212  }
213  }
214 
215  return false;
216 }
217 
218 // ******************************************************************************************
219 // Set the link field with previous value
220 // ******************************************************************************************
221 void KinematicChainWidget::setSelected(const std::string& base_link, const std::string& tip_link)
222 {
223  base_link_field_->setText(QString(base_link.c_str()));
224  tip_link_field_->setText(QString(tip_link.c_str()));
225 }
226 
227 // ******************************************************************************************
228 // Choose the base link
229 // ******************************************************************************************
231 {
232  QTreeWidgetItem* item = link_tree_->currentItem();
233  if (item != nullptr)
234  {
235  base_link_field_->setText(item->text(0));
236  }
237 }
238 
239 // ******************************************************************************************
240 // Choose the tip link
241 // ******************************************************************************************
243 {
244  QTreeWidgetItem* item = link_tree_->currentItem();
245  if (item != nullptr)
246  {
247  tip_link_field_->setText(item->text(0));
248  }
249 }
250 
251 // ******************************************************************************************
252 // Expand/Collapse Tree
253 // ******************************************************************************************
254 void KinematicChainWidget::alterTree(const QString& link)
255 {
256  if (link.contains("expand"))
257  link_tree_->expandAll();
258  else
259  link_tree_->collapseAll();
260 }
261 
262 // ******************************************************************************************
263 // Highlight the currently selected link
264 // ******************************************************************************************
266 {
267  QTreeWidgetItem* item = link_tree_->currentItem();
268  if (item != nullptr)
269  {
270  Q_EMIT unhighlightAll();
271 
272  std::string name = item->text(0).toStdString();
273 
274  // Don't try to highlight empty links!
275  if (name.empty())
276  return;
277 
278  // Check that item is not empty
279  Q_EMIT highlightLink(item->text(0).toStdString(), QColor(255, 0, 0));
280  }
281 }
282 } // namespace moveit_setup_assistant
moveit::core::LinkModel
moveit_setup_assistant::KinematicChainWidget::addLinkChildRecursive
bool addLinkChildRecursive(QTreeWidgetItem *parent, const moveit::core::LinkModel *link, const std::string &parent_name)
Definition: kinematic_chain_widget.cpp:225
moveit_setup_assistant::KinematicChainWidget::itemSelected
void itemSelected()
Highlight the selected link in the kinematic chain.
Definition: kinematic_chain_widget.cpp:297
moveit::core::LinkModel::getChildJointModels
const std::vector< const JointModel * > & getChildJointModels() const
moveit_setup_assistant::KinematicChainWidget::setAvailable
void setAvailable()
Loads the availble data list.
Definition: kinematic_chain_widget.cpp:173
moveit_setup_assistant::KinematicChainWidget::base_link_field_
QLineEdit * base_link_field_
Definition: kinematic_chain_widget.h:83
moveit_setup_assistant::KinematicChainWidget::unhighlightAll
void unhighlightAll()
Event for telling rviz to unhighlight all links of the robot.
kinematic_chain_widget.h
moveit::core::JointModel::getChildLinkModel
const LinkModel * getChildLinkModel() const
moveit_setup_assistant::KinematicChainWidget::KinematicChainWidget
KinematicChainWidget(QWidget *parent, const MoveItConfigDataPtr &config_data)
Constructor.
Definition: kinematic_chain_widget.cpp:85
moveit_setup_assistant::KinematicChainWidget::tipLinkTreeClick
void tipLinkTreeClick()
Choose the tip link.
Definition: kinematic_chain_widget.cpp:274
moveit_setup_assistant::KinematicChainWidget::tip_link_field_
QLineEdit * tip_link_field_
Definition: kinematic_chain_widget.h:84
moveit_setup_assistant::KinematicChainWidget::baseLinkTreeClick
void baseLinkTreeClick()
Choose the base link.
Definition: kinematic_chain_widget.cpp:262
name
name
moveit_setup_assistant::KinematicChainWidget::addLinktoTreeRecursive
void addLinktoTreeRecursive(const moveit::core::LinkModel *link, const moveit::core::LinkModel *parent)
Definition: kinematic_chain_widget.cpp:194
moveit_setup_assistant::KinematicChainWidget::link_tree_
QTreeWidget * link_tree_
Definition: kinematic_chain_widget.h:82
moveit_setup_assistant::KinematicChainWidget::highlightLink
void highlightLink(const std::string &name, const QColor &)
Event for telling rviz to highlight a link of the robot.
moveit_setup_assistant::KinematicChainWidget::config_data_
moveit_setup_assistant::MoveItConfigDataPtr config_data_
Contains all the configuration data for the setup assistant.
Definition: kinematic_chain_widget.h:128
moveit_setup_assistant
Definition: compute_default_collisions.h:46
moveit_setup_assistant::KinematicChainWidget::alterTree
void alterTree(const QString &link)
Expand/Collapse Tree.
Definition: kinematic_chain_widget.cpp:286
moveit_setup_assistant::KinematicChainWidget::setSelected
void setSelected(const std::string &base_link, const std::string &tip_link)
Set the link field with previous value.
Definition: kinematic_chain_widget.cpp:253
moveit::core::LinkModel::getName
const std::string & getName() const
moveit_setup_assistant::KinematicChainWidget::kinematic_chain_loaded_
bool kinematic_chain_loaded_
Remember if the chain tree has been loaded.
Definition: kinematic_chain_widget.h:131
moveit::core::JointModel


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Sat May 3 2025 02:28:04