Skip to content
Snippets Groups Projects

Fix bugs in ArMem and make disk loading and storing nicer

Merged Rainer Kartmann requested to merge armem/fixes into armem/dev
4 files
+ 225
151
Compare changes
  • Side-by-side
  • Inline
Files
4
#include "ControlWidget.h"
#include <QPushButton>
#include <QLineEdit>
#include <QTimer>
#include <RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h>
#include <RobotAPI/libraries/armem/server/query_proc/ltm.h>
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QFileDialog>
#include <QPushButton>
#include <filesystem>
#include <cmath>
@@ -14,60 +20,176 @@ namespace armarx::armem::gui::disk
ControlWidget::ControlWidget()
{
setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Fixed);
_latestDirectory = QString::fromStdString("/tmp/MemoryExport");
auto vlayout = new QVBoxLayout();
auto hlayout1 = new QHBoxLayout();
auto hlayout2 = new QHBoxLayout();
_loadFromDiskButton = new QPushButton(" Load from Disk", this);
_loadFromDiskButton->setIcon(QIcon(":/icons/document-open.svg"));
_storeOnDiskButton = new QPushButton(" Store on Disk", this);
_storeOnDiskButton->setIcon(QIcon(":/icons/document-save.svg"));
hlayout1->setContentsMargins(10, 2, 10, 2);
hlayout2->setContentsMargins(10, 2, 10, 2);
// Allow horizontal shrinking of buttons
std::vector<QPushButton*> buttons { _storeOnDiskButton, _loadFromDiskButton };
for (QPushButton* button : buttons)
{
button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
}
const int margin = 0;
vlayout->setContentsMargins(margin, margin, margin, margin);
this->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Fixed);
_lineEdit = new QLineEdit("/tmp/MemoryExport", this);
//_lineEdit->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
QHBoxLayout* layout = new QHBoxLayout();
this->setLayout(layout);
_openFileBrowserButton = new QPushButton("Search files", this);
const int margin = 0;
layout->setContentsMargins(margin, margin, margin, margin);
layout->addWidget(_loadFromDiskButton);
layout->addWidget(_storeOnDiskButton);
// Connections
connect(_loadFromDiskButton, &QPushButton::pressed, [this]()
{
QString directory = chooseDirectoryDialog();
if (directory.size() > 0)
{
emit requestedLoadFromDisk(directory);
}
});
connect(_storeOnDiskButton, &QPushButton::pressed, [this]()
{
QString directory = chooseDirectoryDialog();
if (directory.size() > 0)
{
emit requestedStoreOnDisk(directory);
}
});
}
_storeOnDiskButton = new QPushButton("Store", this);
_loadFromDiskButton = new QPushButton("Load", this);
hlayout1->addWidget(_lineEdit);
hlayout1->addWidget(_openFileBrowserButton);
static
const std::string&
handleSingular(int num, const std::string& singular, const std::string& plural)
{
return num == 1 ? singular : plural;
}
hlayout2->addWidget(_storeOnDiskButton);
hlayout2->addWidget(_loadFromDiskButton);
vlayout->addItem(hlayout1);
vlayout->addItem(hlayout2);
void
ControlWidget::storeOnDisk(
QString directory,
const std::map<std::string, wm::Memory> memoryData,
std::string* outStatus)
{
std::filesystem::path path(directory.toUtf8().constData());
ARMARX_CHECK_POSITIVE(path.string().size()); // An empty path indicates an error.
std::stringstream status;
if (std::filesystem::is_regular_file(path))
{
status << "Could not export memories contents to " << path << ": Cannot overwrite existing file.";
}
else
{
int numStored = 0;
for (const auto& [name, data] : memoryData)
{
if (std::filesystem::is_regular_file(path / name))
{
status << "Could not export memory '" << name << "' to " << path << ": Cannot overwrite existing file.\n";
}
else
{
std::filesystem::create_directories(path / name);
armem::server::ltm::disk::MemoryManager manager;
manager.setName(name);
manager.setBasePath(path / name);
manager.reload();
manager.append(data);
numStored++;
}
}
status << "Exported " << numStored << " " << handleSingular(numStored, "memory", "memories") << " to " << path << ".";
}
if (outStatus)
{
*outStatus = status.str();
}
}
this->setLayout(vlayout);
// Private connections.
// Public connections.
connect(_openFileBrowserButton, &QPushButton::pressed, this, &This::openFileBrowser);
connect(_loadFromDiskButton, &QPushButton::pressed, this, &This::loadFromDisk);
connect(_storeOnDiskButton, &QPushButton::pressed, this, &This::storeOnDisk);
std::map<std::string, wm::Memory>
ControlWidget::loadFromDisk(
QString directory,
const armem::client::QueryInput& _queryInput,
std::string* outStatus)
{
std::filesystem::path path(directory.toUtf8().constData());
std::map<std::string, wm::Memory> memoryData;
std::stringstream status;
if (not std::filesystem::is_directory(path))
{
status << "Could not import a memory from " << path << ". Skipping import.";
}
else
{
// We use LTM as query target for the disk
armem::client::QueryInput queryInput = _queryInput;
queryInput.addQueryTargetToAll(armem::query::data::QueryTarget::LTM);
const query::data::Input queryIce = queryInput.toIce();
int numLoaded = 0;
for (const auto& dir : std::filesystem::directory_iterator(path))
{
if (dir.is_directory())
{
const std::string key = dir.path().filename();
armem::server::ltm::disk::MemoryManager manager;
manager.setName(key);
manager.setBasePath(path / key);
manager.reload();
armem::server::query_proc::ltm::MemoryQueryProcessor ltm_processor;
armem::wm::Memory query_res = ltm_processor.process(queryIce, manager.getCacheAndLutNotConverted());
manager.convert(query_res);
memoryData[key] = std::move(query_res);
numLoaded++;
}
}
status << "Loaded " << numLoaded << " " << handleSingular(numLoaded, "memory", "memories") << " from " << path << ".";
}
if (outStatus)
{
*outStatus = status.str();
}
return memoryData;
}
void ControlWidget::openFileBrowser()
QString ControlWidget::chooseDirectoryDialog()
{
QFileDialog dialog;
dialog.setFileMode(QFileDialog::DirectoryOnly);
//dialog.setOption(QFileDialog::DontUseNativeDialog, true);
dialog.setOption(QFileDialog::ShowDirsOnly, false);
dialog.exec();
QString open = dialog.directory().path();
_lineEdit->setText(open);
}
QString ControlWidget::getEnteredPath()
{
return _lineEdit->text();
dialog.setDirectory(_latestDirectory);
if (dialog.exec())
{
_latestDirectory = dialog.directory().path();
return _latestDirectory;
}
else
{
return QString::fromStdString("");
}
}
}
Loading