SimoxCSpaceVisualizerWidgetController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package RobotComponents
19 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl.txt
22 * GNU General Public License
23 */
24
26
27#include <unordered_set>
28#include <utility>
29
30#include <QComboBox>
31#include <QDoubleSpinBox>
32#include <QFileDialog>
33#include <QGroupBox>
34#include <QLabel>
35#include <QPushButton>
36#include <QSlider>
37#include <QSpinBox>
38#include <QString>
39#include <QTableWidget>
40#include <QTableWidgetItem>
41#include <QWidget>
42
43#include <VirtualRobot/Robot.h>
44#include <VirtualRobot/RobotNodeSet.h>
45#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualization.h>
46#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h>
47#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationNode.h>
48#include <VirtualRobot/Visualization/Visualization.h>
49
51
53
56#include <RobotComponents/interface/components/MotionPlanning/Tasks/MotionPlanningTask.h>
57
58#include <MotionPlanning/CSpace/CSpaceSampled.h>
59
60void
61clearLayout(QLayout* layout, bool deleteWidgets = true)
62{
63 while (QLayoutItem* item = layout->takeAt(0))
64 {
65 if (deleteWidgets)
66 {
67 if (QWidget* widget = item->widget())
68 {
69 widget->deleteLater();
70 }
71 }
72 if (QLayout* childLayout = item->layout())
73 {
74 clearLayout(childLayout, deleteWidgets);
75 }
76 delete item;
77 }
78}
79
80using namespace armarx;
81
82static const float EDGE_WIDTH{1.f};
83static const armarx::DrawColor EDGE_COLOR_TREE{0.f, 1.f, 0.f, 1.f};
84static const armarx::DrawColor EDGE_COLOR_PATH{0.f, 0.f, 1.f, 1.f};
85
87{
88 widget.setupUi(getWidget());
89
90 visuRoot = nullptr;
91 mutex3D.reset(new RecursiveMutex());
92
93 //global widget settings
94 widget.sliderPathPosition->setScalePosition(QwtSlider::LeadingScale);
95 widget.sliderPathPosition->setScaleStepSize(0.001);
96
97 //add list for server tasks
98
99 motionPlanningServerTaskList = new MotionPlanningServerTaskList{};
100 widget.loadFromServerLayout->addWidget(motionPlanningServerTaskList);
101
102 updateCollisionStateTimer.setSingleShot(true);
103
104 connect(&updateCollisionStateTimer, SIGNAL(timeout()), this, SLOT(updateCollisionState()));
105}
106
107void
109{
110 motionPlanningServerProxyName =
111 settings
112 ->value("motionPlanningServerProxyName",
113 QString::fromStdString(motionPlanningServerProxyName))
114 .toString()
115 .toStdString();
116}
117
118void
120{
121 settings->setValue("motionPlanningServerProxyName",
122 QString::fromStdString(motionPlanningServerProxyName));
123}
124
125QString
127{
128 return "MotionPlanning.SimoxCSpaceVisualizer";
129}
130
131void
133{
134 visuRoot = new SoSeparator();
135 visuRoot->ref();
136
137 // visu agent needs to be at top of tree if coin so that its selection node is found first
138 visuAgent = new SoSeparator();
139 visuAgent->ref();
140 visuRoot->addChild(visuAgent);
141
142 // create the debugdrawer
143 std::string debugDrawerComponentName = generateSubObjectName("DebugDrawer");
144 ARMARX_INFO << "Creating debug drawer component " << debugDrawerComponentName;
146 debugDrawerComponentName);
147
148 if (mutex3D)
149 {
150 debugDrawer->setMutex(mutex3D);
151 }
152 else
153 {
154 ARMARX_ERROR << " No 3d mutex available...";
155 }
156
157 getArmarXManager()->addObject(debugDrawer);
158
159 {
160 std::unique_lock lock(*mutex3D);
161 visuRoot->addChild(debugDrawer->getVisualization());
162 }
163
165 connectSlots();
166
167 usingProxy(motionPlanningServerProxyName);
168}
169
170QPointer<QDialog>
172{
173 if (!dialog)
174 {
175 dialog = new SimpleConfigDialog(parent);
176 dialog->addProxyFinder<MotionPlanningServerInterfacePrx>(
177 {"MotionPlanningServer", "The MotionPlanningServer (empty for none)", "*Server"});
178 }
179 return qobject_cast<SimpleConfigDialog*>(dialog);
180}
181
182void
184{
185 motionPlanningServerProxy =
186 getProxy<MotionPlanningServerInterfacePrx>(motionPlanningServerProxyName);
187 motionPlanningServerTaskList->setMotionPlanningServer(motionPlanningServerProxy);
188 motionPlanningServerTaskList->enableAutoUpdate(true);
190}
191
192SoNode*
194{
195 if (visuRoot)
196 {
197 std::cout << "Returning scene = " << visuRoot->getName() << std::endl;
198 }
199
200 return visuRoot;
201}
202
203void
205{
206 this->mutex3D = mutex3D;
207
208 if (debugDrawer)
209 {
210 debugDrawer->setMutex(mutex3D);
211 }
212}
213
214void
216{
217 connect(widget.pushButtonLoadTask, SIGNAL(clicked()), this, SLOT(loadTask()));
218
219 connect(widget.checkBoxShowTreeEdges, SIGNAL(clicked()), this, SLOT(updateEdgeVisibility()));
220 connect(widget.checkBoxDrawTrace, SIGNAL(clicked(bool)), this, SLOT(drawEdges(bool)));
221
222 connect(widget.doubleSpinBoxTraceStep,
223 SIGNAL(valueChanged(double)),
224 this,
225 SLOT(traceStepChanged()));
226 connect(widget.pushButtonHideAllPaths, SIGNAL(clicked()), this, SLOT(hideAllPaths()));
227
228 connect(widget.pushButtonSetConfig, SIGNAL(clicked()), this, SLOT(setCurrentConfig()));
229 connect(widget.spinBoxPathNumber, SIGNAL(valueChanged(int)), this, SLOT(setCurrentPath()));
230 connect(widget.sliderPathPosition,
231 SIGNAL(valueChanged(double)),
232 this,
233 SLOT(setCurrentPathPosition()));
234 connect(widget.sliderPathPosition,
235 SIGNAL(valueChanged(double)),
236 this,
237 SLOT(setCurrentPathPosition()));
238 connect(widget.checkBoxCollisionNodeHighlighting,
239 SIGNAL(toggled(bool)),
240 this,
241 SLOT(highlightCollisionNodes(bool)));
242 startTimer(timerPeriod);
243}
244
245void
247{
248 if (widget.checkBoxDrawTrace->isChecked())
249 {
250 drawEdges(true);
251 }
252}
253
254void
256{
257 for (std::size_t pIdx = 0; pIdx < paths.size(); ++pIdx)
258 {
259 auto&& path = paths.at(pIdx);
260 debugDrawer->enableLayerVisu(PathData::getEdgeLayerName(pIdx),
261 path.visible && widget.checkBoxShowTreeEdges->isChecked());
262 }
263}
264
265void
267{
268 //switch here if new sources are added
270}
271
272void
274{
276 int newPath = widget.spinBoxPathNumber->value() - 1;
277
278 if (newPath < 0)
279 {
280 return;
281 }
282
283 widget.sliderPathPosition->setScale(0.0, getCurrentPath().getLength());
284 widget.sliderPathPosition->setValue(0);
285 widget.sliderPathPosition->setScaleStepSize(getCurrentPath().getLength() * 0.3);
286 widget.sliderPathPosition->setTotalSteps(100);
287 widget.labelCurrentPathNodeCount->setText(QString::number(getCurrentPath().path.size()));
288 widget.labelCurrentPathTotalLen->setText(QString::number(getCurrentPath().getLength()));
290}
291
292void
294{
295 if (!widget.spinBoxPathNumber->value())
296 {
297 widget.labelCurrentPathCurrentLen->setText(QString::number(0));
298 return;
299 }
300 const auto& path = getCurrentPath().path;
301 const auto& pathAcc = getCurrentPath().accPathLength;
302 const auto val = widget.sliderPathPosition->value();
303 widget.labelCurrentPathCurrentLen->setText(QString::number(val));
304 auto indexTo =
305 std::distance(pathAcc.begin(), std::upper_bound(pathAcc.begin(), pathAcc.end(), val));
306 widget.labelCurrentPathCurrentNode->setText(QString::number(indexTo));
307
308 assert(indexTo >= 0);
309 assert(static_cast<std::size_t>(indexTo) <= path.size());
310
311 if (indexTo == 0)
312 {
313 setAndApplyConfig(path.front());
314 return;
315 }
316
317 if (static_cast<std::size_t>(indexTo) == path.size())
318 {
319 setAndApplyConfig(path.back());
320 return;
321 }
322
323 auto indexFrom = indexTo - 1;
324 auto cfgFrom = path.at(indexFrom);
325 auto cfgTo = path.at(indexTo);
326
327 auto t = (val - pathAcc.at(indexFrom)) / (pathAcc.at(indexTo) - pathAcc.at(indexFrom));
328 VectorXf cfgToSet;
329
330
331 SimoxCSpacePtr simoxcspace = SimoxCSpacePtr::dynamicCast(cspaceUtil);
332 if (!simoxcspace)
333 {
334 CSpaceAdaptorBasePtr simoxcspaceadapter = CSpaceAdaptorBasePtr::dynamicCast(cspaceUtil);
335 if (simoxcspaceadapter)
336 {
337 simoxcspace = SimoxCSpacePtr::dynamicCast(simoxcspaceadapter->getOriginalCSpace());
338 }
339 }
340 if (simoxcspace)
341 {
342 // do robot specific interpolation
343 VirtualRobot::RobotNodeSetPtr rns = VirtualRobot::RobotNodeSet::createRobotNodeSet(
344 simoxcspace->getAgentSceneObj(), "tmp", simoxcspace->getAgentJointNames());
345 Saba::CSpaceSampled tmpCSpace(
346 simoxcspace->getAgentSceneObj(),
347 VirtualRobot::CDManagerPtr(new VirtualRobot::CDManager(simoxcspace->getCD())),
348 rns);
349 Eigen::VectorXf from = Eigen::Map<Eigen::VectorXf>(cfgFrom.data(), cfgFrom.size());
350 Eigen::VectorXf to = Eigen::Map<Eigen::VectorXf>(cfgTo.data(), cfgTo.size());
351 auto config = tmpCSpace.interpolate(from, to, t);
352 cfgToSet = (VectorXf{config.data(), config.data() + config.rows()});
353 }
354 else
355 {
356 std::transform(cfgFrom.begin(),
357 cfgFrom.end(),
358 cfgTo.begin(),
359 std::back_inserter(cfgToSet),
360 [t](float from, float to) { return t * to + (1 - t) * from; });
361 }
362 setAndApplyConfig(cfgToSet);
363}
364
365void
367{
368 if (!cspaceVisu)
369 {
370 return;
371 }
372
373 VectorXf cfg(cspaceVisu->getDimensionality());
374
375 for (std::size_t i = 0; i < cfg.size(); ++i)
376 {
377 cfg.at(i) =
378 dynamic_cast<QDoubleSpinBox*>(widget.tableWidgetDims->cellWidget(i, 2))->value();
379 }
380
381 ARMARX_DEBUG_S << "Setting visu config to: " << cfg;
382
383 const float* it = cfg.data();
384 cspaceVisu->setConfig(it);
385 widget.labelCurrentMinObjDist->setText("loading...");
386 widget.labelCurrentCollisionState->setText("loading...");
387 updateCollisionStateTimer.start(100);
388}
389
390void
392{
393 widget.labelCurrentMinObjDist->setText(QString::number(cspaceVisu->getCD().getDistance()));
394 widget.labelCurrentCollisionState->setText(
395 cspaceVisu->getCD().isInCollision() ? QString{"in collision"} : QString{"no collision"});
396}
397
398void
400{
401 std::vector<std::string> nodeNames;
402 nodeNames.reserve(robotNodes.size());
403 for (const auto& node : robotNodes)
404 {
405 if (node.second)
406 {
407 nodeNames.emplace_back(node.first->getName());
408 }
409 }
410
411 for (std::size_t idxPath = 0; idxPath < paths.size(); ++idxPath)
412 {
413 const auto& pDat = paths.at(idxPath);
414 const auto& p = pDat.path;
415
416 const auto layer = PathData::getEdgeLayerName(idxPath);
417
418 if (p.empty())
419 {
420 continue;
421 }
422
423 //extract poses for each node and cfg
424 const float traceStep = drawTrace
425 ? static_cast<float>(widget.doubleSpinBoxTraceStep->value())
426 : std::numeric_limits<float>::infinity();
427 auto traces = cspaceUtil->getTraceVisu(p, nodeNames, traceStep);
428
429 //draw
430 for (std::size_t i = 0; i < traces.size(); ++i)
431 {
432 DebugDrawerLineSet& trace = traces.at(i);
433 trace.colorFullIntensity = EDGE_COLOR_PATH;
434 trace.colorNoIntensity = EDGE_COLOR_PATH;
435 trace.lineWidth = EDGE_WIDTH;
436 trace.intensities.assign(trace.points.size() / 2, 1);
437 debugDrawer->setLineSetVisu(layer, "trace:" + nodeNames.at(i), trace);
438 }
439 }
440}
441
442void
444{
445 auto&& path = paths.at(index);
446 const bool vis = (state == Qt::Checked);
447 path.visible = vis;
448 debugDrawer->enableLayerVisu(PathData::getEdgeLayerName(index),
449 vis && widget.checkBoxShowTreeEdges->isChecked());
450}
451
452void
454{
455 for (int i = 0; static_cast<std::size_t>(i) < paths.size(); ++i)
456 {
457 dynamic_cast<QCheckBox*>(widget.tableWidgetPaths->cellWidget(i, 0))->setChecked(false);
458 }
459}
460
461void
463{
464 if (!motionPlanningServerProxy)
465 {
466 return;
467 }
468 const auto taskId = motionPlanningServerTaskList->getSelectedId();
469
470 if (!taskId)
471 {
472 return;
473 }
474
475 auto taskCSpaceAndPaths = motionPlanningServerProxy->getTaskCSpaceAndPathsById(*taskId);
476
477 auto& taskCSpace = taskCSpaceAndPaths.cspace;
478
479 if (!taskCSpace)
480 {
481 ARMARX_ERROR_S << "Task with id " << *taskId << " returned an empty cspace!";
482 return;
483 }
484
485 //unwrap cspace adaptors
486 while (taskCSpace->ice_isA(CSpaceAdaptor::ice_staticId()))
487 {
488 if (taskCSpace->ice_isA(ScaledCSpace::ice_staticId()))
489 {
490 auto scalingCSpace = ScaledCSpacePtr::dynamicCast(taskCSpace);
491 for (auto& path : taskCSpaceAndPaths.paths)
492 {
493 scalingCSpace->unscalePath(path);
494 }
495 }
496
497 taskCSpace = CSpaceAdaptorPtr::dynamicCast(taskCSpace)->getOriginalCSpace();
498 }
499
500 if (taskCSpace->ice_isA(SimoxCSpace::ice_staticId()))
501 {
502 SimoxCSpacePtr cspace = SimoxCSpacePtr::dynamicCast(taskCSpace);
503 setSimoxCSpace(cspace);
504 setPaths(std::move(taskCSpaceAndPaths.paths));
505 }
506}
507
508void
514
515void
517{
518 std::unique_lock lock(*mutex3D);
519
520 if (toClear)
521 {
522 toClear->removeAllChildren();
523 toClear->unref();
524 toClear = nullptr;
525 }
526}
527
528void
530{
531 std::unique_lock lock(*mutex3D);
532
533 if (!visuRoot || !toRemove)
534 {
535 return;
536 }
537
538 if (visuRoot->findChild(toRemove) >= 0)
539 {
540 visuRoot->removeChild(toRemove);
541 }
542}
543
544void
546{
547 std::unique_lock lock(*mutex3D);
548
549 if (!visuRoot || !toAdd)
550 {
551 return;
552 }
553
554 if (visuRoot->findChild(toAdd) < 0)
555 {
556 visuRoot->addChild(toAdd);
557 }
558}
559
560void
562{
563 std::unique_lock lock(*mutex3D);
564
565 if (!visuRoot || !toToggle)
566 {
567 return;
568 }
569
570 if (visuRoot->findChild(toToggle) < 0)
571 {
572 visuRoot->addChild(toToggle);
573 }
574 else
575 {
576 visuRoot->removeChild(toToggle);
577 }
578}
579
580void
582{
583 std::unique_lock lock(*mutex3D);
584
585 if (!visuRoot || !child)
586 {
587 return;
588 }
589
590 if (visible)
591 {
592 if (visuRoot->findChild(child) < 0)
593 {
594 visuRoot->addChild(child);
595 }
596 }
597 if (!visible)
598 {
599 if (!(visuRoot->findChild(child) < 0))
600 {
601 visuRoot->removeChild(child);
602 }
603 }
604}
605
606void
608{
610 cspaceUtil = SimoxCSpacePtr::dynamicCast(newCSpace->clone());
611 cspaceVisu = SimoxCSpacePtr::dynamicCast(newCSpace->clone(true));
612 cspaceUtil->initCollisionTest();
613 cspaceVisu->initCollisionTest();
614
615 //set group box "current config"
616 const auto&& dimensions = cspaceUtil->getDimensionsBounds();
617 auto jointNames = cspaceUtil->getAgentJointNames();
618 assert(jointNames.size() == dimensions.size());
619
620 widget.tableWidgetDims->setRowCount(dimensions.size());
621
622 for (std::size_t i = 0; i < dimensions.size(); ++i)
623 {
624 const std::string& name = jointNames.at(i);
625 const FloatRange& bounds = dimensions.at(i);
626
627 widget.tableWidgetDims->setItem(i, 0, new QTableWidgetItem{QString::fromStdString(name)});
628
629 widget.tableWidgetDims->setItem(i, 1, new QTableWidgetItem{QString::number(bounds.min)});
630 auto spinbox = new QDoubleSpinBox{};
631 spinbox->setRange(bounds.min, bounds.max);
632 widget.tableWidgetDims->setCellWidget(i, 2, spinbox);
633 widget.tableWidgetDims->setItem(i, 3, new QTableWidgetItem{QString::number(bounds.max)});
634 spinbox->setSingleStep((bounds.max - bounds.min) / 10000.0);
635 connect(
636 spinbox, SIGNAL(valueChanged(double)), widget.pushButtonSetConfig, SIGNAL(clicked()));
637 }
638
639 visuObjStat.resize(cspaceVisu->getStationaryObjectSet()->getSize());
640 //add visu agent
641 {
642 std::unique_lock lock(*mutex3D);
643 auto robot = cspaceVisu->getAgentSceneObj();
644 robot->setUpdateVisualization(true);
645 robotVisu = robot->getVisualization();
646 ARMARX_IMPORTANT << "Setting visu of robot " << robot.get();
647 auto robotCoinVisu = robotVisu->getCoinVisualization(true);
648 highlightCollisionNodes(widget.checkBoxCollisionNodeHighlighting->checkState() ==
649 Qt::Checked);
650 visuAgent->removeAllChildren();
651 visuAgent->addChild(robotCoinVisu);
652 //add to table
653 auto boxVis = new QCheckBox{QString::fromStdString(robot->getName())};
654 boxVis->setChecked(true);
655 connect(boxVis, SIGNAL(stateChanged(int)), this, SLOT(setVisibilityAgent(int)));
656
657 widget.scrollAreaWidgetContentsObj->layout()->addWidget(boxVis);
658 }
659
660
661 //add visu stat obj
662 for (int i = 0; i < static_cast<int>(visuObjStat.size()); ++i)
663 {
664 auto sceneObj = cspaceVisu->getStationaryObjectSet()->getSceneObject(i);
665 // auto& obj = cspaceVisu->getStationaryObjects().at(i);
666 auto& sep = visuObjStat.at(i);
667 //add visu
668 sep = new SoSeparator();
669 sep->ref();
670 sceneObj->setUpdateVisualization(true);
671 sceneObj->setUpdateCollisionModel(true);
672 auto* visu = dynamic_cast<VirtualRobot::CoinVisualizationNode*>(
673 sceneObj->getVisualization(VirtualRobot::SceneObject::Collision).get());
674 auto coin = visu->getCoinVisualization();
675 ARMARX_INFO << sceneObj->getName() << " visu: " << visu << " coin: " << coin;
676 sep->addChild(coin);
678 //add to table
679 auto boxVis = new IndexedQCheckBox{i, QString::fromStdString(sceneObj->getName())};
680 boxVis->setChecked(true);
681 connect(boxVis,
682 SIGNAL(stateChangedIndex(int, Qt::CheckState)),
683 this,
684 SLOT(setVisibilityObjectStationary(int, Qt::CheckState)));
685 widget.scrollAreaWidgetContentsObj->layout()->addWidget(boxVis);
686 }
687
688
689 //add list of nodes
690 auto nodes = cspaceUtil->getAgentSceneObj()->getRobotNodes();
691 robotNodes.clear();
692 std::transform(nodes.begin(),
693 nodes.end(),
694 std::back_inserter(robotNodes),
695 [](VirtualRobot::RobotNodePtr& nptr) {
696 return std::pair<VirtualRobot::RobotNodePtr, bool>{std::move(nptr), false};
697 });
698
699 //tcps of used kinematic chains are visible per default
700 std::set<std::string> visTcps;
701 const auto& kinematicChainNames = cspaceUtil->getAgent().kinemaicChainNames;
702 std::transform(
703 kinematicChainNames.begin(),
704 kinematicChainNames.end(),
705 std::inserter(visTcps, visTcps.begin()),
706 [this](const std::string& name)
707 { return cspaceUtil->getAgentSceneObj()->getRobotNodeSet(name)->getTCP()->getName(); });
708
709 for (int i = 0; i < static_cast<int>(robotNodes.size()); ++i)
710 {
711 const auto& node = robotNodes.at(i).first;
712 const auto& name = node->getName();
713 bool visible = visTcps.find(name) != visTcps.end();
714 robotNodes.at(i).second = visible;
715
716 auto boxVis = new IndexedQCheckBox{i, QString::fromStdString(node->getName())};
717 boxVis->setChecked(visible);
718 connect(boxVis,
719 SIGNAL(stateChangedIndex(int, Qt::CheckState)),
720 this,
721 SLOT(toggleRobotNodePath(int, Qt::CheckState)));
722 widget.scrollAreaWidgetContentsJoints->layout()->addWidget(boxVis);
723 }
724
725 setCurrentConfig();
726 setEnabledSimoxCSpace();
727}
728
729void
731{
732 robotNodes.at(index).second ^= 1;
733 drawEdges();
734}
735
736void
738{
739 resetPaths();
740
741 assert(paths.empty());
742
743 std::transform(newPaths.begin(),
744 newPaths.end(),
745 std::back_inserter(paths),
746 [](Path& p)
747 {
748 PathData dat;
749 dat.path = std::move(p.nodes);
750
751 float lengthAcc = 0;
752 dat.accPathLength.emplace_back(0);
753 for (std::size_t i = 1; i < dat.path.size(); ++i)
754 {
755 const auto& cfg1 = dat.path.at(i - 1);
756 const auto& cfg2 = dat.path.at(i);
757
758 lengthAcc += euclideanDistance(cfg1.begin(), cfg1.end(), cfg2.begin());
759 dat.accPathLength.emplace_back(lengthAcc);
760 }
761
762 return dat;
763 });
764
765 widget.spinBoxPathNumber->setMaximum(paths.size());
766
767 widget.tableWidgetPaths->setRowCount(paths.size());
768 for (std::size_t i = 0; i < paths.size(); ++i)
769 {
770 const auto& p = paths.at(i);
771 widget.tableWidgetPaths->setItem(
772 i, 1, new QTableWidgetItem{QString::number(p.path.size())});
773 widget.tableWidgetPaths->setItem(
774 i, 2, new QTableWidgetItem{QString::number(p.getLength())});
775
776 auto boxVis = new IndexedQCheckBox{static_cast<int>(i),
777 QString::fromStdString(newPaths.at(i).pathName)};
778 connect(boxVis,
779 SIGNAL(stateChangedIndex(int, Qt::CheckState)),
780 this,
781 SLOT(setVisibilityPath(int, Qt::CheckState)));
782 boxVis->setChecked(true);
783 widget.tableWidgetPaths->setCellWidget(i, 0, boxVis);
784 }
785
786 setEnabledPaths(true);
787 //draw
788 drawEdges();
789 updateEdgeVisibility();
790}
791
792void
794{
795 if (widget.tableWidgetDims->columnCount() < 2)
796 {
797 return;
798 }
799 for (std::size_t i = 0; i < cfg.size() && (int)i < widget.tableWidgetDims->rowCount(); ++i)
800 {
801 auto spinbox = dynamic_cast<QDoubleSpinBox*>(widget.tableWidgetDims->cellWidget(i, 2));
802 if (spinbox)
803 {
804 spinbox->setValue(cfg.at(i));
805 }
806 }
808}
809
810void
812{
813 resetPaths();
815
816 widget.labelCurrentMinObjDist->setText("");
817 widget.tableWidgetDims->clearContents();
818 widget.tableWidgetDims->setRowCount(0);
819
820 clearLayout(widget.scrollAreaWidgetContentsJoints->layout());
821 clearLayout(widget.scrollAreaWidgetContentsObj->layout());
822
823 for (auto& sep : visuObjStat)
824 {
826 }
827 visuObjStat.clear();
828 robotVisu.reset();
829 visuAgent->removeAllChildren();
830 debugDrawer->clearAll();
831 cspaceUtil = nullptr;
832 cspaceVisu = nullptr;
833}
834
835void
837{
838 setEnabledPaths(false);
840 widget.tableWidgetPaths->clearContents();
841 widget.spinBoxPathNumber->setMaximum(0);
842 widget.doubleSpinBoxMovePerMs->setValue(0);
843 paths.clear();
844}
845
846void
848{
849 widget.groupBoxCurCfg->setEnabled(active);
850 widget.groupBoxVisPath->setEnabled(active);
851 widget.groupBoxVisObj->setEnabled(active);
852}
853
854void
856{
857 widget.groupBoxPaths->setEnabled(active);
858 widget.groupBoxPathOpt->setEnabled(active);
859}
860
861void
863{
864 const auto step = widget.doubleSpinBoxMovePerMs->value() * timerPeriod;
865
866 if (widget.checkBoxAnimate->isChecked() && step != 0)
867 {
868 widget.sliderPathPosition->setValue(widget.sliderPathPosition->value() + step);
869 }
870}
871
872void
874{
875 if (!cspaceVisu)
876 {
877 return;
878 }
879 if (!robotVisu)
880 {
881 return;
882 }
883 auto robot = cspaceVisu->getAgentSceneObj();
884 //add visu
885 std::unique_lock lock(*mutex3D);
886 robot->setUpdateVisualization(true);
887
888
889 std::set<std::string> nodesToHighlight;
890 for (auto& setName : cspaceVisu->getAgent().collisionSetNames)
891 {
892 auto set = robot->getRobotNodeSet(setName);
893 for (size_t i = 0; i < set->getSize(); ++i)
894 {
895 VirtualRobot::RobotNodePtr node = set->getNode(i);
896 nodesToHighlight.insert(node->getName());
897 }
898 }
899
900 for (auto& name : nodesToHighlight)
901 {
902 auto node = robot->getRobotNode(name);
903 ARMARX_INFO << "highlighting: " << node->getName() << ": " << enabled;
904 node->highlight(robotVisu, enabled);
905 }
906}
uint8_t index
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
std::shared_ptr< RecursiveMutex > RecursiveMutexPtr
std::shared_ptr< std::recursive_mutex > mutex3D
static TPtr create(Ice::PropertiesPtr properties=Ice::createProperties(), const std::string &configName="", const std::string &configDomain="ArmarX")
Factory method for a component.
Definition Component.h:116
A check box with an index.
static std::string generateSubObjectName(const std::string &superObjectName, const std::string &subObjectName)
Generates a unique name for a sub object from a general name and unique name.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
void setName(std::string name)
Override name of well-known object.
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
void setVisibilityPath(int index, Qt::CheckState state)
Sets the visibility of the given solution path.
void setCurrentConfig()
Updates the current displayed configuration .
void soSeparatorCleanUp(SoSeparator *&toClear)
Cleans up a soseparator.
void soSeparatorToggleRootChild(SoSeparator *toToggle)
Toggles a soseparator's visibility.
void setMutex3D(RecursiveMutexPtr const &mutex3D) override
Sets the mutex used to protect the bullet scene.
void setCurrentPath()
Updates the current path according to the user selection.
void setAndApplyConfig(const VectorXf &cfg)
Sets a configuration and visualizes it.
void soSeparatorAddToRoot(SoSeparator *toAdd)
Adds a soseparator to the root separator.
void soSeparatorRemoveFromRoot(SoSeparator *toRemove)
Removes a soseparator from the root separator.
void setEnabledSimoxCSpace(bool active=true)
Enables or disables the configuration selection and controles for object visibility according to the ...
void soSeparatorRootChildVis(SoSeparator *child, bool visible=true)
void setCurrentPathPosition()
Updates the current position on the current path according to the user selection.
void setVisibilityAgent(int state)
Sets the visibility of the given moveable object.
void soSeparatorCleanUpAndRemoveFromRoot(SoSeparator *&toRemove)
Cleans up a soseparator and removes it from the root separator.
QPointer< QDialog > getConfigDialog(QWidget *parent) override
void setVisibilityObjectStationary(int index, Qt::CheckState state)
Sets the visibility of the given stationary object.
void setSimoxCSpace(SimoxCSpacePtr newCSpace)
Sets a new simox CSpace (and cleans up the old one)
A config-dialog containing one (or multiple) proxy finders.
#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_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
boost::recursive_mutex RecursiveMutex
This file offers overloads of toIce() and fromIce() functions for STL container types.
void clearLayout(QLayout *layout)
IceInternal::Handle< SimoxCSpace > SimoxCSpacePtr
An ice handle for a SimoxCSpace.
Definition SimoxCSpace.h:56
std::vector< float > accPathLength
The path's length up to the i-th node.