39 #include <QDoubleSpinBox>
52 dialog->addProxyFinder<skills::manager::dti::SkillManagerInterfacePrx>(
"SkillManager",
"",
"Skill*");
54 return qobject_cast<SimpleConfigDialog*>(dialog);
58 observerName = dialog->getProxyName(
"SkillManager");
62 observerName = settings->value(
"SkillManager",
"SkillManager").toString().toStdString();
66 settings->setValue(
"SkillManager", QString::fromStdString(observerName));
77 widget.doubleSpinBoxUpdateFreq->setValue(5.0);
78 widget.doubleSpinBoxUpdateFreq->setMinimum(0);
79 widget.doubleSpinBoxUpdateFreq->setMaximum(100);
80 widget.doubleSpinBoxUpdateFreq->setSingleStep(0.5);
81 widget.doubleSpinBoxUpdateFreq->setSuffix(
" Hz");
83 refreshSkillsResultTimer =
new QTimer(
this);
84 refreshSkillsResultTimer->setInterval(1000 / 5);
85 refreshSkillsResultTimer->start();
87 connect(widget.doubleSpinBoxUpdateFreq, &QDoubleSpinBox::editingFinished,
88 this, &SkillManagerMonitorWidgetController::updateTimerFrequency);
89 connect(refreshSkillsResultTimer, &QTimer::timeout,
90 this, &SkillManagerMonitorWidgetController::refreshSkills);
92 connect(widget.pushButtonCopy, &QPushButton::clicked,
93 this, &SkillManagerMonitorWidgetController::copyCurrentConfig);
94 connect(widget.pushButtonPaste, &QPushButton::clicked,
95 this, &SkillManagerMonitorWidgetController::pasteCurrentConfig);
97 connect(widget.pushButtonExecuteSkill, &QPushButton::clicked,
98 this, &SkillManagerMonitorWidgetController::executeSkill);
99 connect(widget.pushButtonStopSkill, &QPushButton::clicked,
100 this, &SkillManagerMonitorWidgetController::stopSkill);
102 connect(widget.treeWidgetSkills, &QTreeWidget::currentItemChanged,
103 this, &SkillManagerMonitorWidgetController::skillSelectionChanged);
105 connect(widget.treeWidgetSkillDetails, &QTreeWidget::itemDoubleClicked,
106 this, &SkillManagerMonitorWidgetController::onTreeWidgetItemDoubleClicked);
123 widget.groupBoxSkills->setTitle(QString::fromStdString(observerName));
124 widget.treeWidgetSkillDetails->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
125 widget.treeWidgetSkillDetails->setColumnHidden(3,
true);
136 widget.treeWidgetSkills->clear();
137 widget.treeWidgetSkillDetails->clear();
138 skillsArgumentsTreeWidgetItem =
nullptr;
139 selectedSkill.providerName =
"";
140 selectedSkill.skillName =
"";
143 void SkillManagerMonitorWidgetController::updateTimerFrequency()
145 int f =
static_cast<int>(std::round(1000 / widget.doubleSpinBoxUpdateFreq->value()));
146 refreshSkillsResultTimer->setInterval(f);
149 void SkillManagerMonitorWidgetController::refreshSkills()
151 static std::map<skills::provider::dto::Execution::Status, std::string> ExecutionStatus2String = {
152 {skills::provider::dto::Execution::Status::Aborted,
"Aborted"},
153 {skills::provider::dto::Execution::Status::Failed,
"Failed"},
154 {skills::provider::dto::Execution::Status::Idle,
"Not yet started"},
156 {skills::provider::dto::Execution::Status::Scheduled,
"Scheduled"},
157 {skills::provider::dto::Execution::Status::Succeeded,
"Succeeded"}
165 auto managerSkills = manager->getSkillDescriptions();
166 std::vector<std::string> removedProviders;
170 std::string providerName = it->first;
171 if (managerSkills.find(providerName) == managerSkills.end())
173 removedProviders.push_back(providerName);
183 std::vector<std::string> newProviders;
184 for (
const auto& [providerName, providerSkills] : managerSkills)
188 skills.insert(std::make_pair(providerName, providerSkills));
189 newProviders.push_back(providerName);
196 while (i < widget.treeWidgetSkills->topLevelItemCount())
198 QTreeWidgetItem* item = widget.treeWidgetSkills->topLevelItem(i);
199 if (std::find(removedProviders.begin(), removedProviders.end(), item->text(0).toStdString()) != removedProviders.end())
201 delete widget.treeWidgetSkills->takeTopLevelItem(i);
210 for (
const auto& [providerName, providerSkills] :
skills)
212 if (
auto it = std::find(newProviders.begin(), newProviders.end(), providerName); it != newProviders.end())
214 auto item =
new QTreeWidgetItem(widget.treeWidgetSkills);
215 item->setText(0, QString::fromStdString(providerName));
216 for (
const auto& [name, sk] : providerSkills)
218 auto itsk =
new QTreeWidgetItem(item);
219 item->addChild(itsk);
220 itsk->setText(0, QString::fromStdString(name));
226 std::map<skills::SkillID, std::string> activeSkillsAndPrefixes;
227 auto managerStatuses = manager->getSkillExecutionStatuses();
228 for (
int i = 0; i < widget.treeWidgetSkills->topLevelItemCount(); ++i)
232 QTreeWidgetItem* item = widget.treeWidgetSkills->topLevelItem(i);
233 auto providerName = item->text(0).toStdString();
235 auto allStatusesForProvider = managerStatuses.at(providerName);
237 for (
int j = 0; j < item->childCount(); ++j)
239 QTreeWidgetItem* skillItem = item->child(j);
240 skills::SkillID currentSkillId(providerName, skillItem->text(0).toStdString());
242 auto statusForSkill = allStatusesForProvider.at(currentSkillId.skillName);
243 skillItem->setText(2, QString::fromStdString(ExecutionStatus2String.at(statusForSkill.header.status)));
245 if (not statusForSkill.header.executorName.empty())
247 activeSkillsAndPrefixes.insert({currentSkillId, statusForSkill.header.executorName});
251 catch (
const std::exception& e)
259 widget.listWidgetActiveSkills->clear();
260 for (
const auto& [
id, prefix] : activeSkillsAndPrefixes)
262 auto prefixedStr =
id.toString(prefix);
264 for (
const auto& [id2, prefix2] : activeSkillsAndPrefixes)
266 auto prefixedStr2 =
id.toString(prefix2);
267 if (prefixedStr == prefixedStr2)
281 widget.listWidgetActiveSkills->addItem(QString::fromStdString(
id.
toString() +
": " +
id.
toString(prefix)));
286 void SkillManagerMonitorWidgetController::executeSkill()
288 if (selectedSkill.providerName.empty() or selectedSkill.skillName.empty())
293 const auto& skillDescriptions =
skills.at(selectedSkill.providerName);
294 if (!skillDescriptions.count(selectedSkill.skillName))
299 auto data = getConfigAsAron();
301 char hostname[HOST_NAME_MAX];
303 gethostname(hostname, HOST_NAME_MAX);
305 skills::manager::dto::SkillExecutionRequest exInfo;
306 exInfo.executorName =
"Skills.Manager GUI (hostname: " + std::string(hostname) +
")";
307 exInfo.skillId = {selectedSkill.providerName, selectedSkill.skillName};
310 ARMARX_IMPORTANT <<
"Executing skill from GUI: " << selectedSkill.providerName <<
"/" << selectedSkill.skillName <<
". The data was: " << data;
312 manager->begin_executeSkill(exInfo);
315 void SkillManagerMonitorWidgetController::stopSkill()
317 if (selectedSkill.providerName.empty() or selectedSkill.skillName.empty())
322 const auto& skillDescriptions =
skills.at(selectedSkill.providerName);
323 if (!skillDescriptions.count(selectedSkill.skillName))
328 ARMARX_INFO <<
"Stopping skill from GUI: " << selectedSkill.providerName <<
"/" << selectedSkill.skillName;
329 manager->abortSkill(selectedSkill.providerName, selectedSkill.skillName);
332 void SkillManagerMonitorWidgetController::skillSelectionChanged(QTreeWidgetItem* current, QTreeWidgetItem*)
334 widget.groupBoxSkillDetails->setEnabled(
false);
342 if (!current->parent())
348 SelectedSkill newSelectedSkill;
351 newSelectedSkill.providerName = current->parent()->text(0).toStdString();
352 newSelectedSkill.skillName = current->text(0).toStdString();
355 widget.groupBoxSkillDetails->setTitle(QString::fromStdString(newSelectedSkill.providerName +
"/" + newSelectedSkill.skillName));
356 widget.groupBoxSkillDetails->setEnabled(
true);
358 if (newSelectedSkill.providerName == selectedSkill.providerName and newSelectedSkill.skillName == selectedSkill.skillName)
363 selectedSkill = newSelectedSkill;
366 widget.treeWidgetSkillDetails->clear();
367 aronTreeWidgetController =
nullptr;
368 skillsArgumentsTreeWidgetItem =
nullptr;
370 auto skillDesc =
skills.at(selectedSkill.providerName).at(selectedSkill.skillName);
373 auto it =
new QTreeWidgetItem(widget.treeWidgetSkillDetails,
374 {QString::fromStdString(
"Name"), QString::fromStdString(skillDesc.skillName)});
375 widget.treeWidgetSkillDetails->addTopLevelItem(it);
379 auto it =
new QTreeWidgetItem(widget.treeWidgetSkillDetails,
380 {QString::fromStdString(
"Robot"), QString::fromStdString(simox::alg::join(skillDesc.robots,
", "))});
381 widget.treeWidgetSkillDetails->addTopLevelItem(it);
385 auto it =
new QTreeWidgetItem(widget.treeWidgetSkillDetails,
386 {QString::fromStdString(
"Description"), QString::fromStdString(skillDesc.description)});
387 widget.treeWidgetSkillDetails->addTopLevelItem(it);
391 auto it =
new QTreeWidgetItem(widget.treeWidgetSkillDetails,
392 {QString::fromStdString(
"Timeout"), QString::fromStdString(std::to_string(skillDesc.timeoutMs)) +
" ms"});
393 widget.treeWidgetSkillDetails->addTopLevelItem(it);
396 skillsArgumentsTreeWidgetItem =
new QTreeWidgetItem(widget.treeWidgetSkillDetails, {QString::fromStdString(
"Arguments")});
400 aronTreeWidgetController = std::make_shared<AronTreeWidgetController>(widget.treeWidgetSkillDetails, skillsArgumentsTreeWidgetItem, aron_args, default_args);
406 if (aronTreeWidgetController)
408 return aronTreeWidgetController->convertToAron();
413 void SkillManagerMonitorWidgetController::copyCurrentConfig()
415 auto data = getConfigAsAron();
422 QClipboard* clipboard = QApplication::clipboard();
423 clipboard->setText(QString::fromStdString(json.dump(2)));
426 void SkillManagerMonitorWidgetController::pasteCurrentConfig()
428 QClipboard* clipboard = QApplication::clipboard();
429 std::string
s = clipboard->text().toStdString();
430 nlohmann::json json = nlohmann::json::parse(
s);
433 if (!aronTreeWidgetController)
438 aronTreeWidgetController->setFromAron(data);
441 void SkillManagerMonitorWidgetController::resetCurrentConfig()
446 void SkillManagerMonitorWidgetController::onTreeWidgetItemDoubleClicked(QTreeWidgetItem* item,
int column)
455 if (item->flags() & Qt::ItemIsEditable)
463 AronTreeWidgetModalCreatorVisitor
v(name, aItem, widget.treeWidgetSkillDetails);
465 auto modal =
v.createdModal;