25#include <RobotAPI/gui-plugins/ArViz/ui_ArVizWidget.h>
32#include <SimoxUtility/algorithm/string/string_tools.h>
45 this_->onGetBatchAsync(batch);
59 widget = std::make_unique<Ui::ArVizWidget>();
62 updateTimer =
new QTimer(
this);
63 connect(updateTimer, &QTimer::timeout,
this, QOverload<>::of(&This::onUpdate));
65 replayTimer =
new QTimer(
this);
66 connect(replayTimer, &QTimer::timeout,
this, QOverload<>::of(&This::onReplayTimerTick));
68 connect(widget->layerTree, &QTreeWidget::itemChanged,
this, &This::layerTreeChanged);
69 connect(widget->expandButton, &QPushButton::clicked,
this, &This::onExpandAll);
70 connect(widget->collapseButton, &QPushButton::clicked,
this, &This::onCollapseAll);
71 connect(widget->filterEdit, &QLineEdit::textChanged,
this, &This::onFilterTextChanged);
72 connect(widget->hideAllButton, &QPushButton::clicked,
this, &This::onHideAll);
73 connect(widget->showAllButton, &QPushButton::clicked,
this, &This::onShowAll);
74 connect(widget->hideFilteredButton, &QPushButton::clicked,
this, &This::onHideFiltered);
75 connect(widget->showFilteredButton, &QPushButton::clicked,
this, &This::onShowFiltered);
77 connect(widget->recordingStartButton, &QPushButton::clicked,
this, &This::onStartRecording);
78 connect(widget->recordingStopButton, &QPushButton::clicked,
this, &This::onStopRecording);
80 connect(widget->refreshRecordingsButton,
81 &QPushButton::clicked,
83 &This::onRefreshRecordings);
84 connect(widget->recordingList,
85 &QListWidget::currentItemChanged,
87 &This::onRecordingSelectionChanged);
89 connect(widget->replayRevisionSpinBox,
90 QOverload<int>::of(&QSpinBox::valueChanged),
92 &This::onReplaySpinChanged);
93 connect(widget->replayRevisionSlider,
94 QOverload<int>::of(&QSlider::valueChanged),
96 &This::onReplaySliderChanged);
98 connect(widget->replayStartButton, &QPushButton::clicked,
this, &This::onReplayStart);
99 connect(widget->replayStopButton, &QPushButton::clicked,
this, &This::onReplayStop);
100 connect(widget->replayTimedButton, &QPushButton::toggled,
this, &This::onReplayTimedStart);
102 connect(widget->exportToVRMLButton, &QPushButton::clicked,
this, &This::exportToVRML);
104 connect(widget->deselectButton, &QPushButton::clicked,
this, &This::onDeselectElement);
105 connect(widget->listInteractiveElements,
106 &QListWidget::itemDoubleClicked,
108 &This::onInteractiveElementSelected);
110 connect(
this, &This::connectGui,
this, &This::onConnectGui, Qt::QueuedConnection);
111 connect(
this, &This::disconnectGui,
this, &This::onDisconnectGui, Qt::QueuedConnection);
115 widget->layerTree, &QTreeWidget::currentItemChanged,
this, &This::updateSelectedLayer);
117 connect(widget->layerInfoTreeGroupBox,
121 connect(widget->defaultShowLimitSpinBox,
122 qOverload<int>(&QSpinBox::valueChanged),
125 layerInfoTree.setMaxElementCountDefault(widget->defaultShowLimitSpinBox->value());
127 layerInfoTree.setWidget(widget->layerInfoTree);
128 layerInfoTree.setEnabled(widget->layerInfoTreeGroupBox->isChecked());
129 layerInfoTree.registerVisualizerCallbacks(visualizer);
133 visualizer.layersChangedCallback = [
this](std::vector<viz::CoinLayerID>
const& layers)
134 { layersChanged(layers); };
138 widget->verticalLayout->addWidget(arvizeProfileLayerWidget);
139 connect(arvizeProfileLayerWidget,
142 &This::updateLayersFromProfile);
143 connect(arvizeProfileLayerWidget,
146 &This::updateLayers);
148 replayTimer->start(33);
158 if (storageName.size() > 0)
162 if (debugObserverName.size() > 0)
168 callbackData->this_ =
this;
169 callback = viz::newCallback_StorageInterface_getRecordingBatch(
178 visualizer.clearCache();
186 if (!debugObserverName.empty())
188 getProxy(debugObserver, debugObserverName,
false,
"",
false);
191 lastTiming = visualizer.getTiming();
192 visualizer.startAsync(storage);
206 ArVizWidgetController::updateLayers()
209 layerTreeChanged(
nullptr, 0);
213 ArVizWidgetController::updateLayersFromProfile()
216 QSignalBlocker blocker(widget->layerTree);
219 for (
int compIndex = 0; compIndex < widget->layerTree->topLevelItemCount(); ++compIndex)
221 QTreeWidgetItem* componentItem = widget->layerTree->topLevelItem(compIndex);
222 bool parentChecked =
true;
223 const std::string
component = componentItem->text(0).toStdString();
224 for (
int layerIndex = 0; layerIndex < componentItem->childCount(); ++layerIndex)
226 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
227 const std::string layer = layerItem->text(0).toStdString();
229 const bool visible = not arvizeProfileLayerWidget->
isHidden(layerID);
230 layerItem->setCheckState(
231 0, visible ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
232 parentChecked &= visible;
235 componentItem->setCheckState(
236 0, parentChecked ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
242 ArVizWidgetController::onConnectGui()
244 onRefreshRecordings();
245 currentRecordingSelected =
false;
248 updateTimer->start(33);
252 ArVizWidgetController::onDisconnectGui()
260 ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item,
int )
263 int componentCount = widget->layerTree->topLevelItemCount();
264 for (
int compIndex = 0; compIndex < componentCount; ++compIndex)
266 QTreeWidgetItem* componentItem = widget->layerTree->topLevelItem(compIndex);
267 std::string
component = componentItem->text(0).toStdString();
268 Qt::CheckState componentCheck = componentItem->checkState(0);
269 int layerCount = componentItem->childCount();
271 arvizeProfileLayerWidget->update(
component, componentCheck == Qt::Checked);
273 if (componentItem == item)
277 << (componentCheck == Qt::Checked);
278 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
280 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
281 if (layerItem->checkState(0) != componentCheck)
283 layerItem->setCheckState(0, componentCheck);
288 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
290 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
291 std::string layer = layerItem->text(0).toStdString();
292 bool layerVisible = (layerItem->checkState(0) == Qt::Checked);
293 ARMARX_VERBOSE <<
"Layer: " << layer <<
", Visible: " << layerVisible;
297 arvizeProfileLayerWidget->update(layerID, layerVisible);
299 visualizer.showLayer(layerID, layerVisible);
305 ArVizWidgetController::layersChanged(std::vector<viz::CoinLayerID>
const& layers)
307 QTreeWidget* tree = widget->layerTree;
309 std::map<std::string, QTreeWidgetItem*> currentComponents;
310 std::map<viz::CoinLayerID, QTreeWidgetItem*> currentLayers;
311 int componentCount = widget->layerTree->topLevelItemCount();
312 for (
int compIndex = 0; compIndex < componentCount; ++compIndex)
314 QTreeWidgetItem* componentItem = widget->layerTree->topLevelItem(compIndex);
315 std::string
component = componentItem->text(0).toStdString();
316 currentComponents.emplace(
component, componentItem);
318 int layerCount = componentItem->childCount();
319 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
321 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
322 std::string layer = layerItem->text(0).toStdString();
325 currentLayers.emplace(layerID, layerItem);
329 const QList<QTreeWidgetItem*> selectedItems = widget->layerTree->selectedItems();
332 QTreeWidgetItem* currentItem =
nullptr;
333 bool componentWasNew =
false;
334 std::string currentComponent;
335 for (
auto& entry : layers)
337 std::string
const&
component = entry.first;
340 auto iter = currentComponents.find(
component);
341 if (iter == currentComponents.end())
344 QSignalBlocker blocker(
346 currentItem =
new QTreeWidgetItem(tree);
347 currentItem->setText(0, QString::fromStdString(
component));
348 currentItem->setCheckState(0,
349 arvizeProfileLayerWidget->isHidden(
component)
353 componentWasNew =
true;
358 currentItem = iter->second;
360 componentWasNew =
false;
366 auto iter = currentLayers.find(entry);
367 if (iter == currentLayers.end())
370 std::string
const& layer = entry.second;
371 QTreeWidgetItem* layerItem =
new QTreeWidgetItem;
372 layerItem->setText(0, QString::fromStdString(layer));
373 layerItem->setCheckState(
374 0, arvizeProfileLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked);
378 currentItem->addChild(layerItem);
383 tree->expandItem(currentItem);
389 <<
"Invalid component/layer ID: " << entry.first <<
" / "
396 if (arvizeProfileLayerWidget->isHidden(iter->first) or
397 iter->second->checkState(0) == Qt::Unchecked)
399 visualizer.showLayer(iter->first,
false);
406 ArVizWidgetController::updateSelectedLayer(QTreeWidgetItem* current, QTreeWidgetItem* previous)
410 if (!current->parent())
418 current->text(0).toStdString());
420 viz::CoinLayer* layer = visualizer.layers.findLayer(
id);
421 if (layer ==
nullptr)
423 ARMARX_WARNING <<
"Could not find layer (" <<
id.first <<
" / " <<
id.second
424 <<
") in Visualizer.";
428 layerInfoTree.setSelectedLayer(
id, &visualizer.layers);
433 ArVizWidgetController::onCollapseAll(
bool)
435 widget->layerTree->collapseAll();
439 ArVizWidgetController::onExpandAll(
bool)
441 widget->layerTree->expandAll();
445 ArVizWidgetController::onHideAll(
bool)
447 showAllLayers(
false);
451 ArVizWidgetController::onShowAll(
bool)
457 ArVizWidgetController::onHideFiltered(
bool)
459 showFilteredLayers(
false);
463 ArVizWidgetController::onShowFiltered(
bool)
465 showFilteredLayers(
true);
469 ArVizWidgetController::onFilterTextChanged(
const QString& filter)
473 QRegExp rx(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
474 for (QTreeWidgetItemIterator iter(widget->layerTree); *iter; ++iter)
476 QTreeWidgetItem* item = *iter;
477 QString itemText = item->text(0);
478 bool matches = filter.size() == 0 || itemText.contains(rx);
479 item->setHidden(!matches);
480 if (matches && item->parent())
483 item->parent()->setHidden(
false);
489 ArVizWidgetController::showAllLayers(
bool visible)
491 widget->layerTree->blockSignals(
true);
493 for (QTreeWidgetItemIterator iter(widget->layerTree); *iter; ++iter)
495 QTreeWidgetItem* item = *iter;
496 item->setCheckState(0, visible ? Qt::Checked : Qt::Unchecked);
499 widget->layerTree->blockSignals(
false);
505 ArVizWidgetController::showFilteredLayers(
bool visible)
507 widget->layerTree->blockSignals(
true);
509 QString filter = widget->filterEdit->text();
510 QRegExp rx(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
512 for (QTreeWidgetItemIterator iter(widget->layerTree); *iter; ++iter)
514 QTreeWidgetItem* item = *iter;
515 QString itemText = item->text(0);
516 bool matches = filter.size() == 0 || itemText.contains(rx);
519 item->setCheckState(0, visible ? Qt::Checked : Qt::Unchecked);
523 widget->layerTree->blockSignals(
false);
529 ArVizWidgetController::onDeselectElement()
533 visualizer.selection->deselectAll();
537 ArVizWidgetController::onContextMenuClicked()
539 viz::ElementInteractionData* selected = visualizer.selectedElement;
540 if (selected ==
nullptr)
542 ARMARX_WARNING <<
"Selected element is null, but a context menu option was clicked!";
546 QPushButton* clickedButton =
static_cast<QPushButton*
>(sender());
548 QLayout* layout = widget->groupBoxContextMenu->layout();
549 int count = layout->count();
550 for (
int i = 0; i < count; ++i)
552 QPushButton* button =
static_cast<QPushButton*
>(layout->itemAt(i)->widget());
553 if (button == clickedButton)
556 visualizer.interactionFeedbackBuffer.emplace_back();
560 interaction.type = viz::data::InteractionFeedbackType::CONTEXT_MENU_CHOSEN;
568 ArVizWidgetController::onInteractiveElementSelected(QListWidgetItem* item)
570 int index = widget->listInteractiveElements->row(item);
576 visualizer.selectElement(
index);
582 std::string
id = inter.
layer.first +
"/" + inter.
layer.second +
"/" + inter.
element;
583 return QString::fromStdString(
id);
587 ArVizWidgetController::onUpdate()
592 QString selectedElementName(
"<None>");
593 QLayout* contextMenuLayout = widget->groupBoxContextMenu->layout();
594 if (visualizer.selectedElement)
596 selectedElementName =
toQString(*visualizer.selectedElement);
599 int currentCount = contextMenuLayout->count();
600 viz::data::InteractionDescription
const& desc = visualizer.selectedElement->interaction;
601 std::vector<std::string>
const& options = desc.contextMenuOptions;
603 if (desc.enableFlags & viz::data::InteractionEnableFlags::CONTEXT_MENU)
605 newCount = (int)options.size();
607 if (newCount != currentCount)
611 while ((item = contextMenuLayout->takeAt(0)) !=
nullptr)
613 delete item->widget();
617 for (std::string
const&
option : options)
619 QPushButton* button =
620 new QPushButton(QString::fromStdString(
option), widget->groupBoxContextMenu);
622 &QPushButton::clicked,
624 &ArVizWidgetController::onContextMenuClicked);
625 contextMenuLayout->addWidget(button);
630 for (
int i = 0; i < currentCount; ++i)
632 QLayoutItem* item = contextMenuLayout->itemAt(i);
633 QPushButton* button =
static_cast<QPushButton*
>(item->widget());
634 button->setText(QString::fromStdString(options[i]));
641 while ((item = contextMenuLayout->takeAt(0)) !=
nullptr)
643 delete item->widget();
647 widget->labelSelectedElement->setText(selectedElementName);
650 int currentCount = widget->listInteractiveElements->count();
651 int newCount = (int)visualizer.elementInteractions.size();
652 if (newCount != currentCount)
654 widget->listInteractiveElements->clear();
655 for (
auto& interaction : visualizer.elementInteractions)
657 QString elementID =
toQString(*interaction);
658 widget->listInteractiveElements->addItem(elementID);
662 onTimingObserverUpdate();
666 ArVizWidgetController::onTimingObserverUpdate()
668 viz::CoinVisualizer_UpdateTiming timing = visualizer.getTiming();
673 timingMap[
"0. pull (ms)"] =
new Variant(timing.
pull.toMilliSecondsDouble());
674 timingMap[
"1. apply (ms)"] =
676 timingMap[
"1.1 apply, addLayer (ms)"] =
678 timingMap[
"1.2 apply, updateElements (ms)"] =
680 timingMap[
"1.3 apply, removeElements (ms)"] =
682 timingMap[
"2. layers (ms)"] =
684 timingMap[
"3. wait duration (ms)"] =
685 new Variant(timing.
waitDuration.toMilliSecondsDouble());
686 timingMap[
"4. update toggle"] =
new Variant(timing.
updateToggle);
687 timingMap[
"total (ms)"] =
new Variant(timing.
total.toMilliSecondsDouble());
689 timings.push_back(timing.
total.toMilliSecondsDouble());
691 if ((
int)timings.size() > numTimings)
693 timings.erase(timings.begin());
696 std::accumulate(timings.begin(), timings.end(), 0.0) / numTimings;
697 timingMap[
"total avg (ms)"] =
new Variant(averageTime);
699 debugObserver->begin_setDebugChannel(
"ArViz_Timing", timingMap);
705 ArVizWidgetController::onStartRecording()
707 std::string recordingID = widget->recordingIdTextBox->text().toStdString();
709 std::string runningID = storage->startRecording(recordingID);
713 if (runningID.size() > 0)
715 std::string message =
"There is already a recording running with ID '" + runningID +
716 "'. \n" +
"You have to stop the running recording first";
717 QMessageBox::information(
718 widget->tabWidget,
"Recording running", QString::fromStdString(message));
726 ArVizWidgetController::onStopRecording()
728 storage->stopRecording();
730 onRefreshRecordings();
735 ArVizWidgetController::onRefreshRecordings()
737 allRecordings = storage->getAllRecordings().recordings;
738 std::sort(allRecordings.begin(),
740 [](viz::data::Recording
const& lhs, viz::data::Recording
const& rhs)
741 { return lhs.id < rhs.id; });
743 std::string currentText;
744 QListWidgetItem* currentItem = widget->recordingList->currentItem();
747 currentText = currentItem->text().toStdString();
750 widget->recordingList->clear();
751 int currentTextIndex = -1;
753 for (
auto& recording : allRecordings)
755 if (recording.id == currentText)
757 currentTextIndex =
index;
759 widget->recordingList->addItem(QString::fromStdString(recording.id));
763 if (currentTextIndex > 0)
765 widget->recordingList->setCurrentRow(currentTextIndex);
770 ArVizWidgetController::onRecordingSelectionChanged(QListWidgetItem* current,
771 QListWidgetItem* previous)
778 std::string selectedID = current->text().toStdString();
779 for (viz::data::Recording
const& recording : allRecordings)
781 if (recording.id == selectedID)
783 selectRecording(recording);
790 timestampToString(
long timestampInMicroSeconds,
bool showMS =
false)
792 IceUtil::Time time = IceUtil::Time::microSeconds(timestampInMicroSeconds);
793 std::string timeString = time.toDateTime();
796 timeString = timeString.substr(0, timeString.size() - 4);
802 ArVizWidgetController::onReplaySpinChanged(
int newValue)
804 widget->replayRevisionSlider->setValue(newValue);
808 ArVizWidgetController::onReplaySliderChanged(
int newValue)
810 if (currentRevision != newValue)
812 long timestamp = replayToRevision(newValue);
815 currentRevision = newValue;
817 widget->replayRevisionSpinBox->setValue(newValue);
820 widget->replayTimestampLabel->setText(
821 QString::fromStdString(timestampToString(
timestamp,
true)));
825 widget->replayRevisionSlider->setValue(currentRevision);
831 ArVizWidgetController::selectRecording(
const viz::data::Recording& recording)
834 widget->recordingIdLabel->setText(QString::fromStdString(recording.id));
836 widget->recordingRevisionLabel->setText(
837 QString::fromStdString(std::to_string(recording.firstRevision) +
" - " +
838 std::to_string(recording.lastRevision)));
840 std::string firstTimeString = timestampToString(recording.firstTimestampInMicroSeconds);
841 std::string lastTimeString = timestampToString(recording.lastTimestampInMicroSeconds);
843 widget->recordingTimestampLabel->setText(
844 QString::fromStdString(firstTimeString +
" - " + lastTimeString));
846 IceUtil::Time duration = IceUtil::Time::microSeconds(
847 recording.lastTimestampInMicroSeconds - recording.firstTimestampInMicroSeconds);
848 int durationSeconds = duration.toSeconds();
849 widget->recordingDurationLabel->setText(
850 QString::fromStdString(std::to_string(durationSeconds) +
" s"));
852 widget->recordingBatchesLabel->setText(
853 QString::fromStdString(std::to_string(recording.batchHeaders.size())));
856 currentRecording = recording;
857 currentRecordingSelected =
true;
858 enableWidgetAccordingToMode();
862 ArVizWidgetController::onReplayStart(
bool)
864 if (!currentRecordingSelected)
866 ARMARX_WARNING <<
"No recording selected, so no replay can be started";
870 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
871 recordingBatchCache.clear();
878 widget->replayRevisionSpinBox->blockSignals(
true);
879 widget->replayRevisionSpinBox->setMinimum(currentRecording.firstRevision);
880 widget->replayRevisionSpinBox->setMaximum(currentRecording.lastRevision);
881 widget->replayRevisionSpinBox->setValue(currentRecording.firstRevision);
882 widget->replayRevisionSpinBox->blockSignals(
false);
884 widget->replayRevisionSlider->blockSignals(
true);
885 widget->replayRevisionSlider->setMinimum(currentRecording.firstRevision);
886 widget->replayRevisionSlider->setMaximum(currentRecording.lastRevision);
887 widget->replayRevisionSlider->setValue(currentRecording.firstRevision);
888 widget->replayRevisionSlider->blockSignals(
false);
890 currentRevision = -1;
891 onReplaySliderChanged(widget->replayRevisionSlider->value());
895 ArVizWidgetController::onReplayStop(
bool)
897 visualizer.startAsync(storage);
903 ArVizWidgetController::replayToRevision(
long revision)
907 ARMARX_WARNING <<
"Cannot call replayToRevision, when not in replaying mode.\n"
908 <<
"Actual mode: " << int(mode);
912 viz::data::RecordingBatchHeader* matchingBatchHeader =
nullptr;
913 for (
auto& batchHeader : currentRecording.batchHeaders)
915 if (batchHeader.firstRevision <= revision && revision <= batchHeader.lastRevision)
917 matchingBatchHeader = &batchHeader;
921 if (matchingBatchHeader ==
nullptr)
923 ARMARX_WARNING <<
"Could not find batch for revision: " << revision;
927 viz::data::RecordingBatch
const& batch = getRecordingBatch(matchingBatchHeader->index);
930 <<
"\nGot batch: " << batch.header.firstRevision <<
" - "
931 << batch.header.lastRevision <<
"\nUpdates: " << batch.updates.size()
932 <<
"\nInitial state: " << batch.initialState.size();
935 auto revisionLess = [](viz::data::TimestampedLayerUpdate
const& lhs,
936 viz::data::TimestampedLayerUpdate
const& rhs)
937 {
return lhs.revision < rhs.revision; };
938 viz::data::TimestampedLayerUpdate pivot;
939 pivot.revision = revision;
941 std::lower_bound(batch.updates.begin(), batch.updates.end(), pivot, revisionLess);
942 auto updateEnd = std::upper_bound(updateBegin, batch.updates.end(), pivot, revisionLess);
945 std::map<std::string, viz::data::LayerUpdate const*> updates;
947 for (
auto& update : batch.initialState)
951 for (
auto updateIter = batch.updates.begin(); updateIter != updateEnd; ++updateIter)
953 updates[updateIter->update.name] = &updateIter->update;
956 auto layerIDsBefore = visualizer.getLayerIDs();
957 for (
auto& pair : updates)
959 visualizer.apply(*pair.second);
961 auto layerIDsAfter = visualizer.getLayerIDs();
962 if (layerIDsAfter != layerIDsBefore)
964 visualizer.emitLayersChanged(layerIDsAfter);
967 return updateBegin->timestampInMicroseconds;
971 ArVizWidgetController::getRevisionForTimestamp(
long timestamp)
975 ARMARX_WARNING <<
"Cannot call replayToTimestamp, when not in replaying mode.\n"
976 <<
"Actual mode: " << int(mode);
980 if (
timestamp < currentRecording.firstTimestampInMicroSeconds)
982 ARMARX_INFO <<
"Requested timestamp is earlier than recording: "
987 viz::data::RecordingBatchHeader* matchingBatchHeader =
nullptr;
988 for (
auto& batchHeader : currentRecording.batchHeaders)
990 matchingBatchHeader = &batchHeader;
991 if (
timestamp <= batchHeader.lastTimestampInMicroSeconds)
997 viz::data::RecordingBatch
const& batch = getRecordingBatch(matchingBatchHeader->index);
999 auto timestampLess = [](viz::data::TimestampedLayerUpdate
const& lhs,
1000 viz::data::TimestampedLayerUpdate
const& rhs)
1001 {
return lhs.timestampInMicroseconds < rhs.timestampInMicroseconds; };
1002 viz::data::TimestampedLayerUpdate pivot;
1003 pivot.timestampInMicroseconds =
timestamp;
1005 std::lower_bound(batch.updates.begin(), batch.updates.end(), pivot, timestampLess);
1006 if (updateEnd == batch.updates.end())
1010 if (updateEnd != batch.updates.begin())
1017 long revisionBeforeTimestamp = updateEnd->revision;
1018 return revisionBeforeTimestamp;
1022 ArVizWidgetController::onReplayTimedStart(
bool checked)
1028 replayCurrentTimestamp = currentTimestamp;
1037 ArVizWidgetController::onReplayTimerTick()
1041 double replaySpeed = widget->replaySpeedSpinBox->value();
1043 long currentRealTime = IceUtil::Time::now().toMicroSeconds();
1044 long elapsedRealTime = currentRealTime - lastReplayRealTime;
1046 replayCurrentTimestamp += elapsedRealTime * replaySpeed;
1048 long revision = getRevisionForTimestamp(replayCurrentTimestamp);
1051 if (widget->replayLoopbackCheckBox->checkState() == Qt::Checked)
1053 replayCurrentTimestamp = currentRecording.firstTimestampInMicroSeconds;
1057 revision = currentRecording.lastRevision;
1062 widget->replayRevisionSlider->setValue(revision);
1066 lastReplayRealTime = IceUtil::Time::now().toMicroSeconds();
1074 enableWidgetAccordingToMode();
1078 ArVizWidgetController::enableWidgetAccordingToMode()
1084 widget->recordingStartButton->setDisabled(
true);
1085 widget->recordingStopButton->setDisabled(
true);
1086 widget->replayStartButton->setDisabled(
true);
1087 widget->replayStopButton->setDisabled(
true);
1088 widget->replayControlGroupBox->setDisabled(
true);
1093 widget->recordingStartButton->setDisabled(
false);
1094 widget->recordingStopButton->setDisabled(
true);
1095 widget->replayStartButton->setDisabled(
false);
1096 widget->replayStopButton->setDisabled(
true);
1097 widget->replayControlGroupBox->setDisabled(
true);
1098 widget->recordingList->setDisabled(
false);
1103 widget->recordingStartButton->setDisabled(
true);
1104 widget->recordingStopButton->setDisabled(
false);
1105 widget->replayStartButton->setDisabled(
true);
1106 widget->replayStopButton->setDisabled(
true);
1107 widget->replayControlGroupBox->setDisabled(
true);
1112 widget->recordingStartButton->setDisabled(
true);
1113 widget->recordingStopButton->setDisabled(
true);
1114 widget->replayStartButton->setDisabled(
true);
1115 widget->replayStopButton->setDisabled(
false);
1116 widget->replayControlGroupBox->setDisabled(
false);
1117 widget->replayRevisionSlider->setDisabled(
false);
1118 widget->replayRevisionSpinBox->setDisabled(
false);
1119 widget->recordingList->setDisabled(
true);
1124 widget->recordingStartButton->setDisabled(
true);
1125 widget->recordingStopButton->setDisabled(
true);
1126 widget->replayStartButton->setDisabled(
true);
1127 widget->replayStopButton->setDisabled(
false);
1128 widget->replayControlGroupBox->setDisabled(
false);
1129 widget->replayRevisionSlider->setDisabled(
true);
1130 widget->replayRevisionSpinBox->setDisabled(
true);
1131 widget->recordingList->setDisabled(
true);
1136 if (!currentRecordingSelected)
1138 widget->replayStartButton->setDisabled(
true);
1139 widget->replayStopButton->setDisabled(
true);
1147 ARMARX_INFO <<
"Received async batch: " << batch.header.index;
1148 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
1150 auto& entry = recordingBatchCache[batch.header.index];
1152 entry.lastUsed = IceUtil::Time::now();
1154 limitRecordingBatchCacheSize();
1156 recordingWaitingForBatchIndex = -1;
1159 viz::data::RecordingBatch
const&
1160 ArVizWidgetController::getRecordingBatch(
long index)
1164 IceUtil::Time now = IceUtil::Time::now();
1166 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
1168 auto iter = recordingBatchCache.find(
index);
1169 if (iter != recordingBatchCache.end())
1172 bool asyncPrefetchIsRunning = callbackResult && !callbackResult->isCompleted();
1173 if (!asyncPrefetchIsRunning && recordingWaitingForBatchIndex == -1)
1175 if (
index + 1 <
long(currentRecording.batchHeaders.size()) &&
1176 recordingBatchCache.count(
index + 1) == 0)
1181 storage->begin_getRecordingBatch(currentRecording.id,
index + 1, callback);
1182 recordingWaitingForBatchIndex =
index + 1;
1183 ARMARX_INFO <<
"Now waiting for " << recordingWaitingForBatchIndex;
1185 else if (
index > 0 && recordingBatchCache.count(
index - 1) == 0)
1190 storage->begin_getRecordingBatch(currentRecording.id,
index - 1, callback);
1191 recordingWaitingForBatchIndex =
index - 1;
1195 TimestampedRecordingBatch& entry = iter->second;
1196 entry.lastUsed = now;
1201 if (
index == recordingWaitingForBatchIndex)
1206 while (recordingWaitingForBatchIndex != -1)
1208 QCoreApplication::processEvents();
1210 return getRecordingBatch(
index);
1214 <<
" is not in the cache. Getting synchronously, blocking GUI...";
1217 auto& newEntry = recordingBatchCache[
index];
1218 newEntry.lastUsed = now;
1219 newEntry.data = storage->getRecordingBatch(currentRecording.id,
index);
1221 limitRecordingBatchCacheSize();
1223 return newEntry.data;
1227 ArVizWidgetController::limitRecordingBatchCacheSize()
1229 if (recordingBatchCache.size() > recordingBatchCacheMaxSize)
1232 auto oldestIter = recordingBatchCache.begin();
1233 for (
auto iter = recordingBatchCache.begin(); iter != recordingBatchCache.end(); ++iter)
1235 TimestampedRecordingBatch& entry = iter->second;
1236 if (entry.lastUsed < oldestIter->second.lastUsed)
1242 recordingBatchCache.erase(oldestIter);
1249 return visualizer.root;
1252 static const std::string CONFIG_KEY_STORAGE =
"Storage";
1253 static const std::string CONFIG_KEY_DEBUG_OBSERVER =
"DebugObserver";
1258 storageName = settings->value(QString::fromStdString(CONFIG_KEY_STORAGE),
"ArVizStorage")
1262 settings->value(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
"DebugObserver")
1270 settings->setValue(QString::fromStdString(CONFIG_KEY_STORAGE),
1271 QString::fromStdString(storageName));
1272 settings->setValue(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
1273 QString::fromStdString(debugObserverName));
1282 configDialog->addProxyFinder<armarx::viz::StorageInterfacePrx>(
1283 {CONFIG_KEY_STORAGE,
"ArViz Storage",
"ArViz*"});
1285 {CONFIG_KEY_DEBUG_OBSERVER,
"Debug observer",
"DebugObserver"});
1287 return qobject_cast<QDialog*>(configDialog);
1295 storageName = configDialog->getProxyName(CONFIG_KEY_STORAGE);
1296 debugObserverName = configDialog->getProxyName(CONFIG_KEY_DEBUG_OBSERVER);
1301 ArVizWidgetController::exportToVRML()
1304 QString fi = QFileDialog::getSaveFileName(
1305 Q_NULLPTR, tr(
"VRML 2.0 File"), QString(), tr(
"VRML Files (*.wrl)"));
1306 std::string s = std::string(fi.toLatin1());
1312 if (!simox::alg::ends_with(s,
".wrl"))
1317 visualizer.exportToVRML(s);
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
void setEnabled(bool enabled)
Enable or disable the layer info tree.
void setMaxElementCountDefault(int max)
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)
A config-dialog containing one (or multiple) proxy finders.
void showLayer(CoinLayerID const &id, bool visible)
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
QString toQString(std::string const &string)
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
bool matches(std::string skillName, std::vector< std::string > &searches)
std::pair< std::string, std::string > CoinLayerID
InteractionDescription interaction()
This file offers overloads of toIce() and fromIce() functions for STL container types.
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
IceUtil::Time updateElements
IceUtil::Time removeElements
IceUtil::Time waitDuration
IceUtil::Time layersChanged
CoinVisualizer_ApplyTiming applyTotal