RobotUnitPluginWidgetController.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::RobotUnitPluginWidgetController
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
24
25#include <RobotAPI/gui-plugins/RobotUnitPlugin/ui_RobotUnitPluginWidget.h>
26
27#include <filesystem>
28#include <regex>
29#include <string>
30
31#include <QAction>
32#include <QDir>
33#include <QSortFilterProxyModel>
34
38
40
41using namespace armarx;
42
44
46{
47 widget = std::make_unique<Ui::RobotUnitPluginWidget>();
48 widget->setupUi(getWidget());
49
50 //add subwidget ControlDevices
51 {
52 controlDevices = new ControlDevicesWidget;
53 widget->groupBoxCDev->layout()->addWidget(controlDevices);
54 widget->groupBoxCDev->setVisible(false);
55 controlDevices->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
56 controlDevices->setVisible(false);
57 }
58 //add subwidget SensorDevices
59 {
60 sensorDevices = new SensorDevicesWidget;
61 widget->groupBoxSDev->layout()->addWidget(sensorDevices);
62 widget->groupBoxSDev->setVisible(false);
63 sensorDevices->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
64 sensorDevices->setVisible(false);
65 }
66 //add subwidget NJointControllers
67 {
68 nJointControllers = new NJointControllersWidget;
69 widget->groupBoxNJointCtrl->layout()->addWidget(nJointControllers);
70 widget->groupBoxNJointCtrl->setVisible(true);
71 nJointControllers->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
72 nJointControllers->setVisible(true);
73 }
74 //add subwidget NJointControllerClasses
75 {
76 nJointControllerClasses = new NJointControllerClassesWidget;
77 widget->groupBoxNJointCtrlClasses->layout()->addWidget(nJointControllerClasses);
78 widget->groupBoxNJointCtrlClasses->setVisible(false);
79 nJointControllerClasses->setSizePolicy(QSizePolicy::MinimumExpanding,
80 QSizePolicy::Expanding);
81 nJointControllerClasses->setVisible(false);
82 }
83 //update logging
84 {
85 widget->groupBoxLogging->setVisible(false);
86 widget->groupBoxLogging->setSizePolicy(QSizePolicy::MinimumExpanding,
87 QSizePolicy::Expanding);
88
89 connect(widget->pushButtonLoggingStart,
90 SIGNAL(clicked()),
91 this,
92 SLOT(on_pushButtonLoggingStart_clicked()));
93 connect(widget->pushButtonLoggingStop,
94 SIGNAL(clicked()),
95 this,
96 SLOT(on_pushButtonLoggingStop_clicked()));
97 connect(widget->pushButtonLoggingMark1,
98 SIGNAL(clicked()),
99 this,
100 SLOT(on_pushButtonLoggingMark1_clicked()));
101 connect(widget->pushButtonLoggingMark2,
102 SIGNAL(clicked()),
103 this,
104 SLOT(on_pushButtonLoggingMark2_clicked()));
105 connect(widget->pushButtonLoggingMark3,
106 SIGNAL(clicked()),
107 this,
108 SLOT(on_pushButtonLoggingMark3_clicked()));
109 connect(widget->lineEditLoggingFilter,
110 SIGNAL(textChanged(const QString&)),
111 this,
112 SLOT(on_lineEditLoggingFilter_textChanged(const QString&)));
113 connect(widget->treeWidgetLoggingNames,
114 SIGNAL(itemChanged(QTreeWidgetItem*, int)),
115 this,
116 SLOT(on_treeWidgetLoggingNames_itemChanged(QTreeWidgetItem*, int)));
117 }
118 updateToolBarActionCheckedState();
119}
120
121void
123{
124 robotUnitProxyName =
125 settings->value("robotUnitProxyName", QString::fromStdString(robotUnitProxyName))
126 .toString()
127 .toStdString();
128 nJointControllerClasses->loadSettings(settings);
129 nJointControllers->loadSettings(settings);
130 controlDevices->loadSettings(settings);
131 sensorDevices->loadSettings(settings);
132 widget->groupBoxCDev->setVisible(settings->value("cdevVisible", false).toBool());
133 widget->groupBoxSDev->setVisible(settings->value("sdevVisible", false).toBool());
134 widget->groupBoxNJointCtrl->setVisible(settings->value("ctrlVisible", true).toBool());
135 widget->groupBoxNJointCtrlClasses->setVisible(settings->value("classVisible", false).toBool());
136 updateToolBarActionCheckedState();
137}
138
139void
141{
142 settings->setValue("robotUnitProxyName", QString::fromStdString(robotUnitProxyName));
143 nJointControllerClasses->saveSettings(settings);
144 nJointControllers->saveSettings(settings);
145 controlDevices->saveSettings(settings);
146 sensorDevices->saveSettings(settings);
147 settings->setValue("cdevVisible", widget->groupBoxCDev->isVisible());
148 settings->setValue("sdevVisible", widget->groupBoxSDev->isVisible());
149 settings->setValue("ctrlVisible", widget->groupBoxNJointCtrl->isVisible());
150 settings->setValue("classVisible", widget->groupBoxNJointCtrlClasses->isVisible());
151}
152
153void
155{
156 usingProxy(robotUnitProxyName);
157 ARMARX_INFO << "RobotUnitPluginWidgetController::onInitComponent()" << std::flush;
158 QMetaObject::invokeMethod(this, "startOnConnectTimer", Qt::QueuedConnection);
159}
160
161void
163{
164 QMetaObject::invokeMethod(this, "stopOnConnectTimer", Qt::QueuedConnection);
165}
166
167void
169{
170 std::lock_guard guard{robotUnitPrxMutex};
171 robotUnitPrx = getProxy<RobotUnitInterfacePrx>(robotUnitProxyName);
172 listenerTopicName = robotUnitPrx->getRobotUnitListenerTopicName();
173 usingTopic(listenerTopicName);
174 updateToolBarActionCheckedState();
175 timerLastIterationRuWasRunning = false;
176}
177
178void
180{
181 std::lock_guard guard{robotUnitPrxMutex};
182 unsubscribeFromTopic(listenerTopicName);
183 robotUnitPrx = nullptr;
184 QMetaObject::invokeMethod(this, "refreshNJointControllersClicked", Qt::QueuedConnection);
185 QMetaObject::invokeMethod(this, "refreshNJointControllerClassesClicked", Qt::QueuedConnection);
186 QMetaObject::invokeMethod(this, "refreshControlDevicesClicked", Qt::QueuedConnection);
187 QMetaObject::invokeMethod(this, "refreshSensorDevicesClicked", Qt::QueuedConnection);
188}
189
190QPointer<QDialog>
192{
193 if (!dialog)
194 {
195 dialog = new SimpleConfigDialog(parent);
196 dialog->addProxyFinder<RobotUnitInterfacePrx>({"RobotUnit", "The RobotUnit", "*"});
197 }
198 return qobject_cast<SimpleConfigDialog*>(dialog);
199}
200
201void
203{
204 robotUnitProxyName = dialog->getProxyName("RobotUnit");
205}
206
207QPointer<QWidget>
209{
210 if (customToolbar)
211 {
212 customToolbar->setParent(parent);
213 }
214 else
215 {
216 customToolbar = new QToolBar(parent);
217 customToolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
218 customToolbar->setIconSize(QSize(16, 16));
219 customToolbar
220 ->addAction(
221 QIcon(":/icons/view-refresh-7.png"), "", this, SLOT(refreshControlDevicesClicked()))
222 ->setToolTip("Update the list of Control Devices");
223 showCDevs = new QAction{"Control Devices", customToolbar};
224 showCDevs->setCheckable(true);
225 showCDevs->setToolTip("Hide/Show the list of Control Devices");
226 connect(showCDevs, SIGNAL(toggled(bool)), widget->groupBoxCDev, SLOT(setVisible(bool)));
227 connect(showCDevs, SIGNAL(toggled(bool)), controlDevices, SLOT(setVisible(bool)));
228 customToolbar->addAction(showCDevs);
229 customToolbar->addSeparator();
230
231 customToolbar
232 ->addAction(
233 QIcon(":/icons/view-refresh-7.png"), "", this, SLOT(refreshSensorDevicesClicked()))
234 ->setToolTip("Update the list of Sensor Devices");
235 showSDevs = new QAction{"Sensor Devices", customToolbar};
236 showSDevs->setCheckable(true);
237 showSDevs->setToolTip("Hide/Show the list of Sensor Devices");
238 connect(showSDevs, SIGNAL(toggled(bool)), widget->groupBoxSDev, SLOT(setVisible(bool)));
239 connect(showSDevs, SIGNAL(toggled(bool)), sensorDevices, SLOT(setVisible(bool)));
240 customToolbar->addAction(showSDevs);
241 customToolbar->addSeparator();
242
243 customToolbar
244 ->addAction(QIcon(":/icons/view-refresh-7.png"),
245 "",
246 this,
247 SLOT(refreshNJointControllersClicked()))
248 ->setToolTip("Update the list of NJointControllers");
249 showNJoint = new QAction{"NJointControllers", customToolbar};
250 showNJoint->setCheckable(true);
251 showNJoint->setToolTip("Hide/Show the list of NJointControllers");
252 connect(
253 showNJoint, SIGNAL(toggled(bool)), widget->groupBoxNJointCtrl, SLOT(setVisible(bool)));
254 connect(showNJoint, SIGNAL(toggled(bool)), nJointControllers, SLOT(setVisible(bool)));
255 customToolbar->addAction(showNJoint);
256 customToolbar->addSeparator();
257
258 customToolbar
259 ->addAction(QIcon(":/icons/view-refresh-7.png"),
260 "",
261 this,
262 SLOT(refreshNJointControllerClassesClicked()))
263 ->setToolTip("Update the list of NJointController Classes");
264 showNJointClasses = new QAction{"NJointController Classes", customToolbar};
265 showNJointClasses->setCheckable(true);
266 showNJointClasses->setToolTip("Hide/Show the list of NJointControllers Classes");
267 connect(showNJointClasses,
268 SIGNAL(toggled(bool)),
269 widget->groupBoxNJointCtrlClasses,
270 SLOT(setVisible(bool)));
271 connect(showNJointClasses,
272 SIGNAL(toggled(bool)),
273 nJointControllerClasses,
274 SLOT(setVisible(bool)));
275 customToolbar->addAction(showNJointClasses);
276 customToolbar->addSeparator();
277
278 customToolbar->addAction(
279 QIcon(":/icons/view-refresh-7.png"), "", this, SLOT(refreshLogging()));
280 showLogging = new QAction{"Logging", customToolbar};
281 showLogging->setCheckable(true);
282 showLogging->setToolTip("Hide/Show the logging pane");
283 connect(showLogging, SIGNAL(toggled(bool)), widget->groupBoxLogging, SLOT(setVisible(bool)));
284 customToolbar->addAction(showLogging);
285 customToolbar->addSeparator();
286
287 customToolbar
288 ->addAction(QIcon(":/icons/document-save.svg"),
289 "Write log",
290 [&]
291 {
292 std::lock_guard guard{robotUnitPrxMutex};
293 robotUnitPrx->writeRecentIterationsToFile(
294 "/tmp/RobotUnitLog-{DateTime}");
295 })
296 ->setToolTip("Writes the log to /tmp/");
297 }
298 updateToolBarActionCheckedState();
299 return customToolbar.data();
300}
301
302void
304 const NJointControllerStatusSeq& status,
305 const Ice::Current&)
306{
307 nJointControllers->nJointControllerStatusChanged(status);
308}
309
310void
312 const Ice::Current&)
313{
314 controlDevices->controlDeviceStatusChanged(status);
315}
316
317void
319 const Ice::Current&)
320{
321 sensorDevices->sensorDeviceStatusChanged(status);
322}
323
324void
326 const Ice::Current&)
327{
328 nJointControllerClasses->nJointControllerClassAdded(name);
329}
330
331void
333 const Ice::Current&)
334{
335 nJointControllers->nJointControllerCreated(name);
336}
337
338void
340 const Ice::Current&)
341{
342 nJointControllers->nJointControllerDeleted(name);
343}
344
345void
346RobotUnitPluginWidgetController::refreshNJointControllersClicked()
347{
348 std::lock_guard guard{robotUnitPrxMutex};
349 nJointControllers->reset(robotUnitPrx);
350}
351
352void
353RobotUnitPluginWidgetController::refreshNJointControllerClassesClicked()
354{
355 std::lock_guard guard{robotUnitPrxMutex};
356 nJointControllerClasses->reset(robotUnitPrx);
357}
358
359void
360RobotUnitPluginWidgetController::refreshControlDevicesClicked()
361{
362 std::lock_guard guard{robotUnitPrxMutex};
363 controlDevices->reset(robotUnitPrx);
364}
365
366void
367RobotUnitPluginWidgetController::refreshSensorDevicesClicked()
368{
369 std::lock_guard guard{robotUnitPrxMutex};
370 sensorDevices->reset(robotUnitPrx);
371}
372
373void
374RobotUnitPluginWidgetController::startOnConnectTimer()
375{
376 if (!timerId)
377 {
378 timerId = startTimer(100);
379 }
380}
381
382void
383RobotUnitPluginWidgetController::stopOnConnectTimer()
384{
385 if (timerId)
386 {
387 killTimer(timerId);
388 timerId = 0;
389 }
390}
391
392void
393RobotUnitPluginWidgetController::updateToolBarActionCheckedState()
394{
395 if (customToolbar)
396 {
397 showCDevs->setChecked(widget->groupBoxCDev->isVisible());
398 showSDevs->setChecked(widget->groupBoxSDev->isVisible());
399 showNJoint->setChecked(widget->groupBoxNJointCtrl->isVisible());
400 showNJointClasses->setChecked(widget->groupBoxNJointCtrlClasses->isVisible());
401 }
402}
403
404void
405armarx::RobotUnitPluginWidgetController::timerEvent(QTimerEvent*)
406{
407 std::lock_guard guard{robotUnitPrxMutex};
408 if (robotUnitPrx && robotUnitPrx->isRunning())
409 {
410 ARMARX_DEBUG << "timerEvent: RobotUnit is running";
411 if (!timerLastIterationRuWasRunning)
412 {
413 refreshNJointControllersClicked();
414 refreshNJointControllerClassesClicked();
415 refreshControlDevicesClicked();
416 refreshSensorDevicesClicked();
417 refreshLogging();
418 }
419 else
420 {
421 loggingData.localLogging();
422 }
423 timerLastIterationRuWasRunning = true;
424 }
425 else
426 {
427 timerLastIterationRuWasRunning = false;
428 ARMARX_DEBUG << "timerEvent: RobotUnit is not running";
429 }
430}
431
432void
433armarx::RobotUnitPluginWidgetController::refreshLogging()
434{
435 std::lock_guard guard{robotUnitPrxMutex};
436 on_pushButtonLoggingStop_clicked();
437
438 widget->treeWidgetLoggingNames->clear();
439 loggingData.allItems.clear();
440
441 const auto allLoggingNames = robotUnitPrx->getLoggingNames();
442
443 std::map<std::string, QTreeWidgetItem*> separators;
444 auto add = [&](const std::string& name, const std::string& display, auto parent)
445 {
446 QTreeWidgetItem* i = new QTreeWidgetItem(parent);
447 i->setText(0, QString::fromStdString(display) + "*");
448 i->setData(0, Qt::ToolTipRole, QString::fromStdString(name));
449 separators[name] = i;
450 loggingData.allItems.emplace_back(i);
451 i->setCheckState(0, Qt::Unchecked);
452 };
453 add("", "", widget->treeWidgetLoggingNames);
454 loggingData.top = loggingData.allItems.front();
455
456 for (const auto& name : allLoggingNames)
457 {
458 const auto parts = Split(name, ".", true, true);
459 std::string reassembled;
460 for (const auto& p : parts)
461 {
462 ARMARX_CHECK_EXPRESSION(separators.count(reassembled));
463 auto parent = separators.at(reassembled);
464 reassembled += (reassembled.empty() ? p : "." + p);
465 if (!separators.count(reassembled))
466 {
467 add(reassembled, p, parent);
468 }
469 }
470 loggingData.allItems.back()->setText(0, QString::fromStdString(parts.back()));
471 }
472}
473
474void
475armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingStart_clicked()
476{
477 std::lock_guard guard{robotUnitPrxMutex};
478 if (!robotUnitPrx || loggingData.handle || loggingData.streamingHandler)
479 {
480 return;
481 }
482 std::vector<std::string> loggingNames;
483 std::function<void(QTreeWidgetItem*)> recurseChildren = [&](auto it)
484 {
485 switch (it->checkState(0))
486 {
487 case Qt::Checked:
488 if (it->childCount() == 0)
489 {
490 loggingNames.emplace_back(
491 it->data(0, Qt::ToolTipRole).toString().toStdString());
492 }
493 else
494 {
495 for (int i = 0; i < it->childCount(); ++i)
496 {
497 recurseChildren(it->child(i));
498 }
499 }
500 break;
501 case Qt::Unchecked:
502 break;
503 case Qt::PartiallyChecked:
504 for (int i = 0; i < it->childCount(); ++i)
505 {
506 recurseChildren(it->child(i));
507 }
508 break;
509 }
510 };
511 recurseChildren(loggingData.top);
512 const std::string saveFormatString = widget->lineEditLoggingPath->text().toStdString();
513 if (widget->checkBoxLoggingStream->isChecked())
514 {
515 ARMARX_INFO << "start streaming " << loggingNames;
516 RobotUnitDataStreaming::Config cfg;
517 cfg.loggingNames = loggingNames;
518 loggingData.streamingHandler =
519 make_shared<RobotUnitDataStreamingReceiver>(this, robotUnitPrx, cfg);
520
521 FileSystemPathBuilder pb{saveFormatString};
522 loggingData.logStream.open(pb.getPath());
523 loggingData.logStream << ";iteration;timestamp;TimeSinceLastIteration";
524 const auto& entries = loggingData.streamingHandler->getDataDescription().entries;
525 std::stringstream str;
526 str << "stream " << entries.size() << " values\n";
527 for (const auto& [name, desc] : entries)
528 {
529 loggingData.logStream << ';' << name;
530 str << " " << name << " -> type " << desc.type << ", index " << desc.index << '\n';
531 }
532 loggingData.logStream << std::endl;
533 ARMARX_INFO << str.str();
534 }
535 else
536 {
537 ARMARX_INFO << "start logging " << loggingNames;
538 loggingData.handle = robotUnitPrx->startRtLogging(saveFormatString, loggingNames);
539 widget->pushButtonLoggingMark1->setEnabled(true);
540 widget->pushButtonLoggingMark2->setEnabled(true);
541 widget->pushButtonLoggingMark3->setEnabled(true);
542 }
543 widget->pushButtonLoggingStart->setEnabled(false);
544 widget->pushButtonLoggingStop->setEnabled(true);
545}
546
547void
548armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingStop_clicked()
549{
550 std::lock_guard guard{robotUnitPrxMutex};
551 widget->pushButtonLoggingStart->setEnabled(true);
552 widget->pushButtonLoggingStop->setEnabled(false);
553 widget->pushButtonLoggingMark1->setEnabled(false);
554 widget->pushButtonLoggingMark2->setEnabled(false);
555 widget->pushButtonLoggingMark3->setEnabled(false);
556 if (loggingData.handle)
557 {
558 robotUnitPrx->stopRtLogging(loggingData.handle);
559 }
560 if (loggingData.logStream.is_open())
561 {
562 loggingData.logStream.close();
563 }
564 loggingData.handle = nullptr;
565 loggingData.streamingHandler = nullptr;
566}
567
568void
569armarx::RobotUnitPluginWidgetController::on_lineEditLoggingFilter_textChanged(const QString& arg1)
570{
571 std::regex reg;
572 try
573 {
574 reg = std::regex{arg1.toStdString()};
575 }
576 catch (...)
577 {
578 //broken regex
579 widget->lineEditLoggingFilter->setStyleSheet(
580 "QLineEdit { background: rgb(255, 150, 150); selection-background-color: rgb(255, 0, "
581 "0); }");
582 return;
583 }
584 widget->lineEditLoggingFilter->setStyleSheet("QLineEdit {}");
585
586 std::function<void(QTreeWidgetItem * item)> setVisible = [&](auto it)
587 {
588 it->setHidden(false);
589 auto parent = it->parent();
590 //set parent state depending on its childrens state
591 if (!parent)
592 {
593 return;
594 }
595 setVisible(parent);
596 };
597 for (auto item : loggingData.allItems)
598 {
599 item->setHidden(true);
600 }
601 for (auto item : loggingData.allItems)
602 {
603 const auto str = item->data(0, Qt::ToolTipRole).toString().toStdString();
604 std::smatch match;
605 if (std::regex_search(str, match, reg))
606 {
607 setVisible(item);
608 }
609 }
610 widget->treeWidgetLoggingNames->blockSignals(true);
611 // Iterate in reverse order
612 for (auto iter = loggingData.allItems.rbegin(); iter != loggingData.allItems.rend(); ++iter)
613 {
614 QTreeWidgetItem* item = *iter;
615 loggingData.updateCheckStateUpward(item, false);
616 }
617 widget->treeWidgetLoggingNames->blockSignals(false);
618}
619
620void
621armarx::RobotUnitPluginWidgetController::on_treeWidgetLoggingNames_itemChanged(
622 QTreeWidgetItem* item,
623 int)
624{
625 widget->treeWidgetLoggingNames->blockSignals(true);
626 loggingData.updateCheckStateDownward(item, item->checkState(0), true);
627 loggingData.updateCheckStateUpward(item->parent(), true);
628 widget->treeWidgetLoggingNames->blockSignals(false);
629}
630
631void
632armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingMark1_clicked()
633{
634 if (!loggingData.handle)
635 {
636 return;
637 }
638 const auto mark = widget->lineEditLoggingMark1->text().toStdString();
639 ARMARX_INFO << "set mark " << mark;
640 robotUnitPrx->addMarkerToRtLog(loggingData.handle, mark);
641}
642
643void
644armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingMark2_clicked()
645{
646 if (!loggingData.handle)
647 {
648 return;
649 }
650 const auto mark = widget->lineEditLoggingMark2->text().toStdString();
651 ARMARX_INFO << "set mark " << mark;
652 robotUnitPrx->addMarkerToRtLog(loggingData.handle, mark);
653}
654
655void
656armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingMark3_clicked()
657{
658 if (!loggingData.handle)
659 {
660 return;
661 }
662 const auto mark = widget->lineEditLoggingMark3->text().toStdString();
663 ARMARX_INFO << "set mark " << mark;
664 robotUnitPrx->addMarkerToRtLog(loggingData.handle, mark);
665}
666
667void
668RobotUnitPluginWidgetController::LoggingData::updateCheckStateUpward(QTreeWidgetItem* item,
669 bool recurseParents)
670{
671 //set item state depending on its childrens state and maybe recurse parent
672 for (; item; item = recurseParents ? item->parent() : nullptr)
673 {
674 if (item->isHidden())
675 {
676 continue;
677 }
678 bool anyChecked = false;
679 bool anyUnchecked = false;
680 bool anyTri = false;
681 for (int i = 0; i < item->childCount(); ++i)
682 {
683 auto c = item->child(i);
684 if (c->isHidden())
685 {
686 continue;
687 }
688 switch (c->checkState(0))
689 {
690 case Qt::Checked:
691 anyChecked = true;
692 break;
693 case Qt::Unchecked:
694 anyUnchecked = true;
695 break;
696 case Qt::PartiallyChecked:
697 anyTri = true;
698 break;
699 }
700 if (anyChecked + anyUnchecked + anyTri > 1 || anyTri)
701 {
702 item->setCheckState(0, Qt::PartiallyChecked);
703 }
704 else if (anyChecked)
705 {
706 item->setCheckState(0, Qt::Checked);
707 }
708 else if (anyUnchecked)
709 {
710 item->setCheckState(0, Qt::Unchecked);
711 }
712 //case all false -> leaf -> do nothing
713 }
714 }
715}
716
717void
718RobotUnitPluginWidgetController::LoggingData::updateCheckStateDownward(QTreeWidgetItem* item,
719 Qt::CheckState state,
720 bool recurseChildren)
721{
722 if (item->isHidden())
723 {
724 return;
725 }
726 item->setCheckState(0, state);
727
728 if (!recurseChildren)
729 {
730 return;
731 }
732 for (int i = 0; i < item->childCount(); ++i)
733 {
734 auto c = item->child(i);
735 if (c->isHidden())
736 {
737 continue;
738 }
739 c->setCheckState(0, state);
740 updateCheckStateDownward(c, state, true);
741 }
742}
743
744void
745RobotUnitPluginWidgetController::LoggingData::localLogging()
746{
747 if (!streamingHandler)
748 {
749 ARMARX_DEBUG_S << "localLogging -> no local logging";
750 return;
751 }
752 ARMARX_DEBUG_S << "localLogging -> do local logging";
753 auto& data = streamingHandler->getDataBuffer();
754 if (data.empty())
755 {
756 ARMARX_INFO_S << ::deactivateSpam() << "No streaming data received!";
757 return;
758 }
759 ARMARX_INFO_S << ::deactivateSpam(1) << "Writing " << data.size() << " timesteps";
760 const auto& descr = streamingHandler->getDataDescription();
761 for (const auto& step : data)
762 {
763 for (const auto& [name, desc] : descr.entries)
764 {
765 logStream << ';' << step.iterationId << ';' << step.timestampUSec << ';'
766 << step.timesSinceLastIterationUSec;
767 using enum_t = RobotUnitDataStreaming::DataEntryType;
768 switch (desc.type)
769 {
770 case enum_t::NodeTypeBool:
771 logStream << ';' << step.bools.at(desc.index);
772 break;
773 case enum_t::NodeTypeByte:
774 logStream << ';' << step.bytes.at(desc.index);
775 break;
776 case enum_t::NodeTypeShort:
777 logStream << ';' << step.shorts.at(desc.index);
778 break;
779 case enum_t::NodeTypeInt:
780 logStream << ';' << step.ints.at(desc.index);
781 break;
782 case enum_t::NodeTypeLong:
783 logStream << ';' << step.longs.at(desc.index);
784 break;
785 case enum_t::NodeTypeFloat:
786 logStream << ';' << step.floats.at(desc.index);
787 break;
788 case enum_t::NodeTypeDouble:
789 logStream << ';' << step.doubles.at(desc.index);
790 break;
791 };
792 }
793 logStream << std::endl;
794 }
795 data.clear();
796}
uint8_t data[1]
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
constexpr T c
std::string str(const T &t)
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
bool unsubscribeFromTopic(const std::string &name)
Unsubscribe from a topic.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
QPointer< QWidget > getCustomTitlebarWidget(QWidget *parent) override
getTitleToolbar returns a pointer to the a toolbar widget of this controller.
void nJointControllerCreated(const std::string &name, const Ice::Current &) override
void nJointControllerDeleted(const std::string &name, const Ice::Current &) override
void controlDeviceStatusChanged(const ControlDeviceStatusSeq &status, const Ice::Current &) override
void nJointControllerClassAdded(const std::string &name, const Ice::Current &) override
void configured() override
Callback called when the config dialog is closed.
void sensorDeviceStatusChanged(const SensorDeviceStatusSeq &status, const Ice::Current &) override
void nJointControllerStatusChanged(const NJointControllerStatusSeq &status, const Ice::Current &) override
QPointer< QDialog > getConfigDialog(QWidget *parent) override
void reset(RobotUnitInterfacePrx ru)
void setVisible(bool visible) override
A config-dialog containing one (or multiple) proxy finders.
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:203
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:179
#define ARMARX_INFO_S
Definition Logging.h:200
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:182
This file offers overloads of toIce() and fromIce() functions for STL container types.
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotUnitInterface > RobotUnitInterfacePrx
auto make_shared(Args &&... args)
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
constexpr auto entries(std::index_sequence< I... >) noexcept
Helps to build a path via format strings: All format strings are of the form '{[^{}...