ControlDevicesWidget.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * \package RobotAPI::gui-plugins::RobotUnitPlugin
17  * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * \date 2017
19  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 #include "ControlDevicesWidget.h"
23 
24 #include <QCheckBox>
25 
26 #include "StyleSheets.h"
27 
28 namespace armarx
29 {
31  RobotUnitWidgetTemplateBase("ControlDevicesWidget", parent)
32  {
33  ui->treeWidget->setColumnCount(8);
34  QTreeWidgetItem* head = ui->treeWidget->headerItem();
35  head->setText(idxName, "Name");
36  head->setText(idxTags, "Tags");
37  head->setText(idxMode, "Mode");
38  head->setText(idxHWMode, "HardwareMode");
39  head->setText(idxAct, "Act");
40  head->setText(idxReq, "Req");
41  head->setText(idxType, "Target Type");
42  head->setText(idxVal, "Target Value");
43 
44  head->setToolTip(
45  idxName,
46  "The control device's name (green: ok, red: missmatch between requested and active "
47  "mode, orange: active/requested device not found in the displayed list)");
48  head->setToolTip(idxTags, "The control device's tags");
49  head->setToolTip(idxMode, "The control device's control mode");
50  head->setToolTip(idxHWMode, "The control device's hardware control mode");
51  head->setToolTip(idxAct,
52  "Whether the control mode is active (green: ok, red: missmatch between "
53  "requested and active mode)");
54  head->setToolTip(idxReq,
55  "Whether the control mode is requested (green: ok, red: missmatch between "
56  "requested and active mode)");
57  head->setToolTip(idxType, "The control mode's target type");
58  head->setToolTip(idxVal, "The control mode's target value");
59 
60  ui->treeWidget->setColumnWidth(idxName, 150);
61  ui->treeWidget->setColumnWidth(idxTags, 100);
62  ui->treeWidget->setColumnWidth(idxMode, 225);
63  ui->treeWidget->setColumnWidth(idxHWMode, 110);
64  ui->treeWidget->setColumnWidth(idxAct, 40);
65  ui->treeWidget->setColumnWidth(idxReq, 40);
66  ui->treeWidget->setColumnWidth(idxType, 350);
67  ui->treeWidget->header()->setResizeMode(idxAct, QHeaderView::Fixed);
68  ui->treeWidget->header()->setResizeMode(idxReq, QHeaderView::Fixed);
69  }
70 
72  {
73  delete ui;
74  }
75 
76  void
77  ControlDevicesWidget::controlDeviceStatusChanged(const ControlDeviceStatusSeq& allStatus)
78  {
79  std::unique_lock<std::recursive_timed_mutex> guard{mutex, std::defer_lock};
80  if (!guard.try_lock_for(std::chrono::microseconds(100)))
81  {
82  return;
83  }
84  for (const auto& status : allStatus)
85  {
86  if (statusUpdates[status.deviceName].timestampUSec < status.timestampUSec)
87  {
88  statusUpdates[status.deviceName] = status;
89  if (doMetaCall)
90  {
91  QMetaObject::invokeMethod(this, "updateContent", Qt::QueuedConnection);
92  }
93  }
94  }
95  }
96 
97  void
99  {
100  entries.clear();
101  statusUpdates.clear();
102  resetData.clear();
103  }
104 
105  void
107  {
108  for (const auto& pair : statusUpdates)
109  {
110  update(pair.second);
111  }
112  statusUpdates.clear();
113  }
114 
115  void
117  {
118  auto temp = robotUnit->getControlDeviceDescriptions();
119  {
120  std::unique_lock<std::recursive_timed_mutex> guard{mutex};
121  resetData = std::move(temp);
122  }
123  }
124 
125  bool
127  {
128  if (resetData.empty())
129  {
130  return true;
131  }
132  add(resetData.back());
133  resetData.pop_back();
134  return false;
135  }
136 
137  void
138  ControlDevicesWidget::add(const ControlDeviceDescription& desc)
139  {
140  std::unique_lock<std::recursive_timed_mutex> guard{mutex};
141  if (entries.count(desc.deviceName))
142  {
143  return;
144  }
145  entries[desc.deviceName] = new ControlDevicesWidgetEntry(*this, *(ui->treeWidget), desc);
146  }
147 
148  void
149  ControlDevicesWidget::update(const ControlDeviceStatus& status)
150  {
151  std::unique_lock<std::recursive_timed_mutex> guard{mutex};
152  if (!robotUnit || !robotUnit->isRunning())
153  {
154  return;
155  }
156  if (!entries.count(status.deviceName))
157  {
158  add(robotUnit->getControlDeviceDescription(status.deviceName));
159  }
160  entries.at(status.deviceName)->update(status);
161  }
162 
164  QTreeWidget& treeWidget,
165  const ControlDeviceDescription& desc) :
166  QObject{&parent}
167  {
168  header = new QTreeWidgetItem;
169  treeWidget.addTopLevelItem(header);
170  header->setText(ControlDevicesWidget::idxName, QString::fromStdString(desc.deviceName));
171  //tags
172  {
173  QCheckBox* boxTags = new QCheckBox{QString::number(desc.tags.size()) + " Tags"};
174  treeWidget.setItemWidget(header, ControlDevicesWidget::idxTags, boxTags);
175  boxTags->setStyleSheet(checkboxStyleSheet());
176  boxTags->setChecked(false);
177  connect(boxTags, SIGNAL(clicked(bool)), this, SLOT(hideTagList(bool)));
178  for (const auto& tag : desc.tags)
179  {
180  QTreeWidgetItem* child = new QTreeWidgetItem{{QString::fromStdString(tag)}};
181  treeWidget.addTopLevelItem(child);
182  tags.emplace_back(child);
183  }
184  }
185  for (const auto& nameToType : desc.contolModeToTargetType)
186  {
187  ControllerEntry& subEntry = subEntries[nameToType.first];
188  subEntry.child = new QTreeWidgetItem;
189  header->addChild(subEntry.child);
190  subEntry.child->setText(ControlDevicesWidget::idxMode,
191  QString::fromStdString(nameToType.first));
192  subEntry.child->setText(ControlDevicesWidget::idxHWMode,
193  QString::fromStdString(nameToType.second.hardwareControlMode));
194  subEntry.child->setText(ControlDevicesWidget::idxAct, " ");
195  subEntry.child->setText(ControlDevicesWidget::idxReq, " ");
196  subEntry.child->setText(ControlDevicesWidget::idxType,
197  QString::fromStdString(nameToType.second.targetType));
198  subEntry.value = new VariantWidget;
199  treeWidget.setItemWidget(subEntry.child, ControlDevicesWidget::idxVal, subEntry.value);
200  }
201  }
202 
203  void
204  ControlDevicesWidgetEntry::update(const ControlDeviceStatus& status)
205  {
206  auto colorNew = (status.activeControlMode == status.requestedControlMode) ? green() : red();
207  bool newDevsNotFound = false;
208  if (activeMode != status.activeControlMode)
209  {
210  if (subEntries.count(activeMode))
211  {
212  subEntries.at(activeMode).child->setText(ControlDevicesWidget::idxAct, " ");
213  subEntries.at(activeMode)
214  .child->setBackgroundColor(ControlDevicesWidget::idxAct, transparent());
215  }
216  activeMode = status.activeControlMode;
217  if (subEntries.count(activeMode))
218  {
219  newDevsNotFound = true;
220  subEntries.at(activeMode).child->setText(ControlDevicesWidget::idxAct, "X");
221  }
222  }
223  if (requestedMode != status.requestedControlMode)
224  {
225  if (subEntries.count(requestedMode))
226  {
227  subEntries.at(requestedMode).child->setText(ControlDevicesWidget::idxReq, " ");
228  subEntries.at(requestedMode)
229  .child->setBackgroundColor(ControlDevicesWidget::idxReq, transparent());
230  }
231  requestedMode = status.requestedControlMode;
232  if (subEntries.count(requestedMode))
233  {
234  newDevsNotFound = true;
235  subEntries.at(requestedMode).child->setText(ControlDevicesWidget::idxReq, "X");
236  }
237  }
238  //color
239  {
240  //set the color here, since active may change without requested changen (or the other way) -> above there is no update
241  if (subEntries.count(requestedMode))
242  {
243  subEntries.at(requestedMode)
244  .child->setBackgroundColor(ControlDevicesWidget::idxReq, colorNew);
245  }
246  if (subEntries.count(activeMode))
247  {
248  subEntries.at(activeMode)
249  .child->setBackgroundColor(ControlDevicesWidget::idxAct, colorNew);
250  }
251  header->setBackgroundColor(ControlDevicesWidget::idxName,
252  newDevsNotFound ? orange() : colorNew);
253  }
254  for (const auto& pair : status.controlTargetValues)
255  {
256  if (subEntries.count(pair.first))
257  {
258  subEntries.at(pair.first).value->update(pair.second);
259  subEntries.at(pair.first).value->layout()->setContentsMargins(0, 0, 0, 0);
260  }
261  }
262  }
263 
264  bool
266  {
267  return header->text(ControlDevicesWidget::idxName).contains(name, Qt::CaseInsensitive);
268  }
269 
270  bool
272  {
273  for (const auto& tagit : tags)
274  {
275  if (tagit->text(ControlDevicesWidget::idxTags).contains(tag, Qt::CaseInsensitive))
276  {
277  return true;
278  }
279  }
280  return false;
281  }
282 
283  std::set<QTreeWidgetItem*>
285  {
286  std::set<QTreeWidgetItem*> hits;
287  for (const auto& pair : subEntries)
288  {
289  if (pair.second.child->text(ControlDevicesWidget::idxMode)
290  .contains(mode, Qt::CaseInsensitive))
291  {
292  hits.emplace(pair.second.child);
293  }
294  }
295  return hits;
296  }
297 
298  std::set<QTreeWidgetItem*>
300  {
301  std::set<QTreeWidgetItem*> hits;
302  for (const auto& pair : subEntries)
303  {
304  if (pair.second.child->text(ControlDevicesWidget::idxAct)
305  .contains(state, Qt::CaseInsensitive))
306  {
307  hits.emplace(pair.second.child);
308  }
309  }
310  return hits;
311  }
312 
313  std::set<QTreeWidgetItem*>
315  {
316  std::set<QTreeWidgetItem*> hits;
317  for (const auto& pair : subEntries)
318  {
319  if (pair.second.child->text(ControlDevicesWidget::idxReq)
320  .contains(state, Qt::CaseInsensitive))
321  {
322  hits.emplace(pair.second.child);
323  }
324  }
325  return hits;
326  }
327 
328  std::set<QTreeWidgetItem*>
330  {
331  std::set<QTreeWidgetItem*> hits;
332  for (const auto& pair : subEntries)
333  {
334  if (pair.second.child->text(ControlDevicesWidget::idxType)
335  .contains(type, Qt::CaseInsensitive))
336  {
337  hits.emplace(pair.second.child);
338  }
339  }
340  return hits;
341  }
342 
343  void
345  {
346  if (!vis)
347  {
348  hideTagList(true);
349  }
350  header->setHidden(!vis);
351  }
352 
353  void
354  ControlDevicesWidgetEntry::setChildVis(bool vis, std::set<QTreeWidgetItem*> children)
355  {
356  for (const auto& pair : subEntries)
357  {
358  if (children.count(pair.second.child))
359  {
360  pair.second.child->setHidden(!vis);
361  }
362  else
363  {
364  pair.second.child->setHidden(vis);
365  }
366  }
367  }
368 
369  void
370  ControlDevicesWidgetEntry::hideTagList(bool hide)
371  {
372  for (QTreeWidgetItem* tag : tags)
373  {
374  tag->setHidden(hide);
375  }
376  }
377 } // namespace armarx
armarx::ControlDevicesWidget::idxHWMode
static constexpr int idxHWMode
Definition: ControlDevicesWidget.h:76
armarx::ControlDevicesWidget::idxType
static constexpr int idxType
Definition: ControlDevicesWidget.h:79
armarx::ControlDevicesWidgetEntry::matchName
bool matchName(const QString &name)
Definition: ControlDevicesWidget.cpp:265
armarx::checkboxStyleSheet
QString checkboxStyleSheet()
Definition: StyleSheets.h:31
armarx::ControlDevicesWidget::idxAct
static constexpr int idxAct
Definition: ControlDevicesWidget.h:77
armarx::ControlDevicesWidgetEntry::matchTargetType
std::set< QTreeWidgetItem * > matchTargetType(const QString &type)
Definition: ControlDevicesWidget.cpp:329
armarx::ControlDevicesWidget::idxTags
static constexpr int idxTags
Definition: ControlDevicesWidget.h:74
armarx::ControlDevicesWidgetEntry::matchTag
bool matchTag(const QString &tag)
Definition: ControlDevicesWidget.cpp:271
armarx::RobotUnitWidgetTemplateBase< Ui::ControlDevicesWidget >::ui
Ui::ControlDevicesWidget * ui
Definition: RobotUnitWidgetBase.h:134
armarx::ControlDevicesWidget
Definition: ControlDevicesWidget.h:51
armarx::ControlDevicesWidgetEntry::ControlDevicesWidgetEntry
ControlDevicesWidgetEntry(ControlDevicesWidget &parent, QTreeWidget &treeWidget, const ControlDeviceDescription &desc)
Definition: ControlDevicesWidget.cpp:163
armarx::ControlDevicesWidget::idxVal
static constexpr int idxVal
Definition: ControlDevicesWidget.h:80
armarx::RobotUnitWidgetBase::doMetaCall
std::atomic_bool doMetaCall
Definition: RobotUnitWidgetBase.h:99
armarx::ControlDevicesWidget::controlDeviceStatusChanged
void controlDeviceStatusChanged(const ControlDeviceStatusSeq &allStatus)
Definition: ControlDevicesWidget.cpp:77
armarx::ControlDevicesWidgetEntry::matchMode
std::set< QTreeWidgetItem * > matchMode(const QString &mode)
Definition: ControlDevicesWidget.cpp:284
armarx::status
status
Definition: FiniteStateMachine.h:244
armarx::ControlDevicesWidgetEntry::isActiveState
std::set< QTreeWidgetItem * > isActiveState(const QString &state)
Definition: ControlDevicesWidget.cpp:299
armarx::RobotUnitWidgetBase::robotUnit
RobotUnitInterfacePrx robotUnit
Definition: RobotUnitWidgetBase.h:93
armarx::ControlDevicesWidgetEntry::setVisible
void setVisible(bool vis)
Definition: ControlDevicesWidget.cpp:344
armarx::RobotUnitWidgetBase::mutex
std::recursive_timed_mutex mutex
Definition: RobotUnitWidgetBase.h:94
armarx::ControlDevicesWidgetEntry::update
void update(const ControlDeviceStatus &status)
Definition: ControlDevicesWidget.cpp:204
armarx::ControlDevicesWidget::ControlDevicesWidget
ControlDevicesWidget(QWidget *parent=0)
Definition: ControlDevicesWidget.cpp:30
armarx::ControlDevicesWidget::idxMode
static constexpr int idxMode
Definition: ControlDevicesWidget.h:75
armarx::RobotUnitWidgetTemplateBase
Definition: RobotUnitWidgetBase.h:106
armarx::ControlDevicesWidget::doContentUpdate
void doContentUpdate() override
Definition: ControlDevicesWidget.cpp:106
armarx::ControlDevicesWidget::idxName
static constexpr int idxName
Definition: ControlDevicesWidget.h:73
armarx::red
QColor red()
Definition: StyleSheets.h:78
armarx::ControlDevicesWidget::clearAll
void clearAll() override
Definition: ControlDevicesWidget.cpp:98
armarx::ControlDevicesWidget::~ControlDevicesWidget
~ControlDevicesWidget() override
Definition: ControlDevicesWidget.cpp:71
armarx::ControlDevicesWidget::addOneFromResetData
bool addOneFromResetData() override
Definition: ControlDevicesWidget.cpp:126
ControlDevicesWidget.h
armarx::ControlDevicesWidgetEntry::isRequestedState
std::set< QTreeWidgetItem * > isRequestedState(const QString &state)
Definition: ControlDevicesWidget.cpp:314
armarx::ControlDevicesWidgetEntry::setChildVis
void setChildVis(bool vis, std::set< QTreeWidgetItem * > children)
Definition: ControlDevicesWidget.cpp:354
armarx::ControlDevicesWidget::getResetData
void getResetData() override
Definition: ControlDevicesWidget.cpp:116
armarx::transparent
QColor transparent()
Definition: StyleSheets.h:90
armarx::ControlDevicesWidget::idxReq
static constexpr int idxReq
Definition: ControlDevicesWidget.h:78
armarx::orange
QColor orange()
Definition: StyleSheets.h:84
StyleSheets.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::green
QColor green()
Definition: StyleSheets.h:72