39 static const int OBJECTS_COLUMN_ATTACHMENT = 6;
45 widget.objectsTree->clear();
46 widget.objectsTree->sortItems(0, Qt::SortOrder::AscendingOrder);
47 widget.objectsTree->setContextMenuPolicy(Qt::CustomContextMenu);
49 widget.requestTree->clear();
50 widget.requestTree->sortItems(0, Qt::SortOrder::AscendingOrder);
55 connect(widget.updateButton, &QPushButton::pressed,
this, &This::updateTab);
56 connect(widget.tabWidget, &QTabWidget::currentChanged,
this, &This::updateTab);
57 connect(widget.detchAllButton,
58 &QPushButton::pressed,
60 this->detachAllObjectsFromRobotNodes(
61 widget.detchAllCommitAttachedCheckBox->isChecked());
64 connect(widget.objectsTree,
65 &QTreeWidget::customContextMenuRequested,
67 &This::prepareObjectContextMenu);
69 connect(widget.requestButton, &QPushButton::pressed,
this, &This::requestSelectedObjects);
71 QTimer* timer =
new QTimer(
this);
72 timer->setInterval(500);
73 connect(timer, &QTimer::timeout,
this, &This::updateTab);
74 connect(widget.autoUpdateCheckBox,
90 ObjectPoseGuiWidgetController::~ObjectPoseGuiWidgetController()
95 ObjectPoseGuiWidgetController::loadSettings(QSettings* settings)
101 ObjectPoseGuiWidgetController::saveSettings(QSettings* settings)
107 ObjectPoseGuiWidgetController::GetWidgetName()
109 return "ArMem.ObjectPoseGui";
112 static const std::string CONFIG_KEY_OBJECT_POSE_STORAGE =
"ObjectPoseStorage";
115 ObjectPoseGuiWidgetController::getConfigDialog(QWidget* parent)
121 {CONFIG_KEY_OBJECT_POSE_STORAGE,
"Object pose storage",
"Object*"});
123 return qobject_cast<QDialog*>(configDialog);
127 ObjectPoseGuiWidgetController::configured()
131 objectPoseStorageName = configDialog->getProxyName(CONFIG_KEY_OBJECT_POSE_STORAGE);
132 if (objectPoseStorageName.empty())
134 objectPoseStorageName =
"ObjectMemory";
140 ObjectPoseGuiWidgetController::onInitComponent()
142 if (!objectPoseStorageName.empty())
144 usingProxy(objectPoseStorageName);
149 ObjectPoseGuiWidgetController::onConnectComponent()
151 if (!objectPoseStorageName.empty())
153 getProxy(ObjectPoseStorage, objectPoseStorageName);
156 this->attachableFrames = ObjectPoseStorage->getAttachableFrames();
157 std::sort(attachableFrames.begin(),
158 attachableFrames.end(),
159 [](
const auto& lhs,
const auto& rhs) { return lhs.agent < rhs.agent; });
160 for (objpose::AgentFrames& frames : attachableFrames)
162 std::sort(frames.frames.begin(), frames.frames.end());
170 ObjectPoseGuiWidgetController::onDisconnectComponent()
172 ObjectPoseStorage =
nullptr;
176 ObjectPoseGuiWidgetController::updateTab()
178 if (widget.tabWidget->currentWidget() == widget.tabObjects)
182 else if (widget.tabWidget->currentWidget() == widget.tabRequest)
189 ObjectPoseGuiWidgetController::updateObjectsTab()
191 if (!ObjectPoseStorage)
201 ARMARX_VERBOSE <<
"Got " << objectPosesIce.size() <<
" object poses. "
202 <<
"(Took " << (IceUtil::Time::now() - start).toMilliSecondsDouble()
207 std::map<std::string, objpose::ObjectPoseSeq> objectPosesByProvider;
208 for (
const auto& pose : objectPoses)
210 objectPosesByProvider[pose.providerName].push_back(pose);
213 start = IceUtil::Time::now();
215 QTreeWidget* tree = widget.objectsTree;
221 QTreeWidgetItem* item =
new QTreeWidgetItem({QString::fromStdString(provider)});
227 bool expand = item->childCount() == 0;
235 QTreeWidgetItem* item =
new QTreeWidgetItem(QStringList{});
242 item->setText(col++, QString::fromStdString(pose.
objectID.
str()));
243 item->setText(col++, QString::fromStdString(pose.
providerName));
245 QString::fromStdString(
249 std::stringstream ss;
252 static const Eigen::IOFormat iof(5, 0,
"",
" x ",
"",
"",
"",
"");
253 ss << pose.
localOOBB->dimensions().format(iof);
259 item->setText(col++, QString::fromStdString(ss.str()));
261 item->setText(col++, QString::number(
double(pose.
confidence),
'g', 2));
266 std::stringstream ss;
272 item->setText(col++, QString::fromStdString(ss.str()));
281 item->setExpanded(
true);
286 builder.
updateTree(tree, objectPosesByProvider);
289 << (IceUtil::Time::now() - start).toMilliSecondsDouble() <<
" ms.";
293 ObjectPoseGuiWidgetController::updateRequestTab()
295 if (!ObjectPoseStorage)
303 objpose::ProviderInfoMap availableProvidersInfo =
304 ObjectPoseStorage->getAvailableProvidersInfo();
305 ARMARX_VERBOSE <<
"Got infos of " << availableProvidersInfo.size()
306 <<
" object pose providers. "
307 <<
"(Took " << (IceUtil::Time::now() - start).toMilliSecondsDouble()
312 std::map<std::string, std::set<std::pair<std::string, std::string>>>
data;
313 for (
const auto& [providerName, info] : availableProvidersInfo)
315 for (
const auto&
id : info.supportedObjects)
317 data[
id.dataset].insert(std::make_pair(
id.className, providerName));
321 start = IceUtil::Time::now();
323 QTreeWidget* tree = widget.requestTree;
327 [](
const std::string& dataset,
const auto&)
329 QTreeWidgetItem* item =
new QTreeWidgetItem({QString::fromStdString(dataset)});
334 const std::string& dataset,
const auto& datasetData, QTreeWidgetItem* datasetItem)
340 [](
const std::pair<std::string, std::string>& lhs, QTreeWidgetItem* item)
342 auto rhs = std::make_pair(item->text(0).toStdString(),
343 item->text(1).toStdString());
348 return lhs == rhs ? 0 : 1;
351 [](
const std::pair<std::string, std::string>& element)
353 QTreeWidgetItem* item =
354 new QTreeWidgetItem({QString::fromStdString(element.first),
355 QString::fromStdString(element.second)});
359 [tree](
const std::pair<std::string, std::string>& element,
360 QTreeWidgetItem* item)
363 if (!tree->itemWidget(item, 2))
365 QCheckBox* requestCheckBox =
new QCheckBox();
366 tree->setItemWidget(item, 2, requestCheckBox);
377 << (IceUtil::Time::now() - start).toMilliSecondsDouble() <<
" ms.";
381 ObjectPoseGuiWidgetController::prepareObjectContextMenu(
const QPoint& pos)
383 QTreeWidget* tree = widget.objectsTree;
384 QTreeWidgetItem* item = tree->itemAt(pos);
386 if (item ==
nullptr || item->parent() ==
nullptr)
392 QString providerName = item->parent()->text(0);
393 QString objectID = item->text(0);
395 QMenu* attachMenu =
new QMenu(
"Attach to robot node", tree);
396 for (
const objpose::AgentFrames& agentFrames : attachableFrames)
398 QMenu* agentMenu =
new QMenu(QString::fromStdString(agentFrames.agent), tree);
400 for (
const std::string& frame : agentFrames.frames)
402 QAction* attachAgentAction =
new QAction(QString::fromStdString(frame), tree);
404 connect(attachAgentAction,
407 this->attachObjectToRobotNode(
408 providerName, objectID, agentFrames.agent, frame);
410 agentMenu->addAction(attachAgentAction);
412 attachMenu->addMenu(agentMenu);
415 QAction* detachAction =
new QAction(tr(
"Detach from to robot node"), tree);
416 detachAction->setEnabled(!item->text(OBJECTS_COLUMN_ATTACHMENT).isEmpty());
417 connect(detachAction,
419 [=,
this]() { this->detachObjectFromRobotNode(providerName, objectID); });
422 menu.addMenu(attachMenu);
423 menu.addAction(detachAction);
425 menu.exec(tree->mapToGlobal(pos));
429 ObjectPoseGuiWidgetController::attachObjectToRobotNode(QString providerName,
431 const std::string& agentName,
432 const std::string& frameName)
434 ARMARX_VERBOSE <<
"Attaching " << objectID <<
" by '" << providerName <<
"' to robot node '"
435 << frameName <<
"' of agent '" << agentName <<
"'.";
437 objpose::AttachObjectToRobotNodeInput
input;
438 input.providerName = providerName.toStdString();
440 input.agentName = agentName;
441 input.frameName = frameName;
445 objpose::AttachObjectToRobotNodeOutput output =
446 ObjectPoseStorage->attachObjectToRobotNode(
input);
449 catch (
const IceUtil::Exception& e)
452 <<
input.frameName <<
"' of agent '" <<
input.agentName <<
"'."
453 <<
"\nReason: " << e.what();
458 ObjectPoseGuiWidgetController::detachObjectFromRobotNode(QString providerName, QString objectID)
460 ARMARX_VERBOSE <<
"Detaching " << objectID <<
" by '" << providerName
461 <<
"' from robot node.";
463 objpose::DetachObjectFromRobotNodeInput
input;
464 input.providerName = providerName.toStdString();
469 objpose::DetachObjectFromRobotNodeOutput output =
470 ObjectPoseStorage->detachObjectFromRobotNode(
input);
473 catch (
const IceUtil::Exception& e)
476 <<
"' from a robot node."
477 <<
"\nReason: " << e.what();
482 ObjectPoseGuiWidgetController::detachAllObjectsFromRobotNodes(
bool commitAttachedPose)
485 objpose::DetachAllObjectsFromRobotNodesInput
input;
486 input.commitAttachedPose = commitAttachedPose;
490 objpose::DetachAllObjectsFromRobotNodesOutput output =
491 ObjectPoseStorage->detachAllObjectsFromRobotNodes(
input);
492 ARMARX_VERBOSE <<
"Detached " << output.numDetached <<
" objects from robot nodes.";
494 catch (
const IceUtil::Exception& e)
496 ARMARX_WARNING <<
"Failed to detach all objects from robot nodes.";
501 ObjectPoseGuiWidgetController::requestSelectedObjects()
503 std::map<std::string, objpose::observer::RequestObjectsInput> requestsPerProvider;
505 QTreeWidget* tree = widget.requestTree;
506 for (
int i = 0; i < tree->topLevelItemCount(); ++i)
508 QTreeWidgetItem* datasetItem = tree->topLevelItem(i);
509 for (
int j = 0; j < datasetItem->childCount(); ++j)
511 QTreeWidgetItem* classItem = datasetItem->child(j);
512 QCheckBox* selected =
dynamic_cast<QCheckBox*
>(tree->itemWidget(classItem, 2));
514 if (selected->isChecked())
516 std::string providerName = classItem->text(1).toStdString();
517 objpose::observer::RequestObjectsInput& requests =
518 requestsPerProvider[providerName];
520 id.dataset = datasetItem->text(0).toStdString();
521 id.className = classItem->text(0).toStdString();
527 if (!widget.requestInfiniteCheckBox->isChecked())
529 timeoutMS = long(widget.requestTimeoutSpinBox->value() * 1000);
532 for (
auto& [providerName, request] : requestsPerProvider)
534 request.provider = providerName;
535 request.request.relativeTimeoutMS = timeoutMS;
537 ARMARX_INFO <<
"Requesting " << request.request.objectIDs.size() <<
" objects for "
538 << request.request.relativeTimeoutMS <<
" ms.";
539 objpose::observer::RequestObjectsOutput output =
540 ObjectPoseStorage->requestObjects(request);
542 for (
const auto& [
id, result] : output.results)
544 successful += int(!result.providerName.empty() && result.result.success);
546 ARMARX_INFO << successful <<
" of " << request.request.objectIDs.size()
547 <<
" object request successful.";