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