22#include <QDoubleValidator>
24#include <QStandardItemModel>
41 : QMainWindow(parent),
44 _viewerPropertiesWidget(0),
45 _optimizerPropertiesWidget(0),
48 leKernelWidth->setValidator(
new QDoubleValidator(
49 -numeric_limits<double>::max(), numeric_limits<double>::max(), 7,
this));
50 plainTextEdit->setMaximumBlockCount(1000);
52 QObject::connect(cbDrawAxis, SIGNAL(toggled(
bool)), viewer,
53 SLOT(setAxisIsDrawn(
bool)));
59 QString filename = QFileDialog::getOpenFileName(
60 this,
"Load g2o file",
"",
"g2o files (*.g2o);;All Files (*)");
61 if (!filename.isNull()) {
67 QString filename = QFileDialog::getSaveFileName(
this,
"Save g2o file",
"",
69 if (!filename.isNull()) {
70 ofstream fout(filename.toStdString().c_str());
71 viewer->graph->save(fout);
73 cerr <<
"Saved " << filename.toStdString() << endl;
75 cerr <<
"Error while saving file" << endl;
80 if (viewer->graph->vertices().size() == 0 ||
81 viewer->graph->edges().size() == 0) {
82 cerr <<
"Graph has no vertices / edges" << endl;
86 bool allocatedNewSolver;
88 if (!allocateStatus) {
89 cerr <<
"Error while allocating solver" << endl;
92 if (allocatedNewSolver)
prepare();
101 int maxIterations = spIterations->value();
102 int iter = viewer->graph->optimize(maxIterations);
103 if (maxIterations > 0 && !iter) {
104 cerr <<
"Optimization failed, result might be invalid" << endl;
108 btnForceStop->hide();
110 viewer->setUpdateDisplay(
true);
116 if (viewer->graph->activeEdges().size() == 0)
117 viewer->graph->initializeOptimization();
119 switch (cbxIniitialGuessMethod->currentIndex()) {
122 viewer->graph->computeInitialGuess();
128 viewer->graph->computeInitialGuess(costFunction);
136 viewer->setUpdateDisplay(
true);
141 if (viewer->graph->activeEdges().size() == 0)
142 viewer->graph->initializeOptimization();
144 viewer->graph->setToOrigin();
145 viewer->setUpdateDisplay(
true);
151 cerr <<
"reloading " <<
_filename << endl;
152 viewer->graph->clear();
154 viewer->setUpdateDisplay(
true);
160 if (viewer->graph->vertices().size() == 0 ||
161 viewer->graph->edges().size() == 0) {
166 bool gaugeFreedom = viewer->graph->gaugeFreedom();
170 cerr <<
"cannot find a vertex to fix in this thing" << endl;
173 cerr <<
"graph is fixed by node " << gauge->
id() << endl;
177 cerr <<
"graph is fixed by priors or nodes are already fixed" << endl;
180 viewer->graph->setVerbose(
true);
187 coOptimizer->clear();
192 bool varFound =
false;
194 for (OptimizationAlgorithmFactory::CreatorList::const_iterator it =
195 knownSolvers.begin();
196 it != knownSolvers.end(); ++it) {
198 if (sp.
name ==
"gn_var" || sp.
name ==
"gn_var_cholmod") {
206 for (OptimizationAlgorithmFactory::CreatorList::const_iterator it =
207 knownSolvers.begin();
208 it != knownSolvers.end(); ++it) {
210 if (sp.
type == varType) {
211 coOptimizer->addItem(QString::fromStdString(sp.
name));
217 map<string, vector<OptimizationAlgorithmProperty> > solverLookUp;
219 for (OptimizationAlgorithmFactory::CreatorList::const_iterator it =
220 knownSolvers.begin();
221 it != knownSolvers.end(); ++it) {
223 if (varFound && varType == sp.
type)
continue;
224 solverLookUp[sp.
type].push_back(sp);
227 for (map<
string, vector<OptimizationAlgorithmProperty> >::iterator it =
228 solverLookUp.begin();
229 it != solverLookUp.end(); ++it) {
231 coOptimizer->insertSeparator(coOptimizer->count());
234 const vector<OptimizationAlgorithmProperty>& vsp = it->second;
235 for (
size_t j = 0; j < vsp.size(); ++j) {
236 coOptimizer->addItem(QString::fromStdString(vsp[j].name));
243 viewer->graph->clear();
244 bool loadStatus =
false;
245 if (filename ==
"-") {
246 cerr <<
"reading stdin" << endl;
247 loadStatus = viewer->graph->load(cin);
249 ifstream ifs(filename.toStdString().c_str());
250 if (!ifs)
return false;
251 loadStatus = viewer->graph->load(ifs);
253 if (!loadStatus)
return false;
255 viewer->setUpdateDisplay(
true);
262 if (sp.
name ==
"" && sp.
desc ==
"")
continue;
265 qobject_cast<QStandardItemModel*>(coOptimizer->model())
267 ->setEnabled(suitableSolver);
273 if (coOptimizer->count() == 0) {
274 cerr <<
"No solvers available" << endl;
277 int currentIndex = coOptimizer->currentIndex();
278 bool enabled = qobject_cast<QStandardItemModel*>(coOptimizer->model())
283 cerr <<
"selected solver is not enabled" << endl;
289 allocatedNewSolver =
true;
290 QString strSolver = coOptimizer->currentText();
295 viewer->graph->setAlgorithm(0);
296 delete algorithmPointer;
312 cerr <<
"Marginalizing Landmarks" << endl;
313 for (SparseOptimizer::VertexIDMap::const_iterator it =
315 it != optimizer->
vertices().end(); ++it) {
323 cerr <<
"Preparing (no marginalization of Landmarks)" << endl;
324 for (SparseOptimizer::VertexIDMap::const_iterator it =
326 it != optimizer->
vertices().end(); ++it) {
332 viewer->graph->initializeOptimization();
338 bool robustKernel = cbRobustKernel->isChecked();
339 double huberWidth = leKernelWidth->text().toDouble();
342 bool onlyLoop = cbOnlyLoop->isChecked();
345 QString strRobustKernel = coRobustKernel->currentText();
349 cerr << strRobustKernel.toStdString() <<
" is not a valid robust kernel"
353 for (SparseOptimizer::EdgeSet::const_iterator it =
354 optimizer->
edges().begin();
355 it != optimizer->
edges().end(); ++it) {
369 for (SparseOptimizer::EdgeSet::const_iterator it =
370 optimizer->
edges().begin();
371 it != optimizer->
edges().end(); ++it) {
381 viewer->graph->clear();
382 bool loadStatus =
load(filename);
386 cerr <<
"loaded " << filename.toStdString() <<
" with "
387 << viewer->graph->vertices().size() <<
" vertices and "
388 << viewer->graph->edges().size() <<
" measurements" << endl;
395 viewer->setBackgroundColor(QColor::fromRgb(255, 255, 255));
400 viewer->setBackgroundColor(QColor::fromRgb(51, 51, 51));
417 tr(
"Internal Solver Properties"));
419 bool allocatedNewSolver;
421 if (!allocateStatus) {
422 cerr <<
"Error while allocating solver" << endl;
425 if (allocatedNewSolver)
prepare();
436 QString selectedFilter;
437 QString filename = QFileDialog::getSaveFileName(
438 this,
"Save screen to a file",
"viewer.png",
439 "PNG files (*.png);;JPG files (*.jpg);;EPS files (*.eps)",
442 if (!filename.isNull()) {
444 int spacePos = selectedFilter.indexOf(
' ');
445 assert(spacePos > 0 &&
"extracting the image format failed");
446 QString format = selectedFilter.left(spacePos);
448 if (format ==
"JPG") {
449 viewer->setSnapshotQuality(90);
451 viewer->setSnapshotQuality(-1);
453 viewer->setSnapshotFormat(format);
454 viewer->saveSnapshot(filename);
455 cerr <<
"saved snapshot " << filename.toStdString() <<
"("
456 << format.toStdString() <<
")" << endl;
461 QString filename = QFileDialog::getOpenFileName(
462 this,
"Load State",
"camera.xml",
"Camera/State file (*.xml)");
463 if (!filename.isEmpty()) {
464 viewer->setStateFileName(filename);
465 viewer->restoreStateFromFile();
466 viewer->setStateFileName(QString());
468 cerr <<
"Loaded state from " << filename.toStdString() << endl;
473 QString filename = QFileDialog::getSaveFileName(
474 this,
"Save State",
"camera.xml",
"Camera/State file (*.xml)");
475 if (!filename.isEmpty()) {
476 viewer->setStateFileName(filename);
477 viewer->saveStateToFile();
478 viewer->setStateFileName(QString());
479 cerr <<
"Saved state to " << filename.toStdString() << endl;
484 coRobustKernel->clear();
485 std::vector<std::string> kernels;
487 for (
size_t i = 0; i < kernels.size(); ++i) {
488 coRobustKernel->addItem(QString::fromStdString(kernels[i]));
void on_btnOptimizerParameters_clicked()
void updateDisplayedSolvers()
bool allocateSolver(bool &allocatedNewSolver)
void on_actionSave_Viewer_State_triggered(bool)
void on_btnOptimize_clicked()
bool loadFromFile(const QString &filename)
void updateRobustKernels()
ViewerPropertiesWidget * _viewerPropertiesWidget
void on_btnSetZero_clicked()
g2o::OptimizationAlgorithm * _currentSolver
void on_actionSave_triggered(bool)
PropertiesWidget * _optimizerPropertiesWidget
void on_actionProperties_triggered(bool)
std::vector< g2o::OptimizationAlgorithmProperty > _knownSolvers
void on_btnInitialGuess_clicked()
void on_actionLoad_triggered(bool)
g2o::OptimizationAlgorithmProperty _currentOptimizationAlgorithmProperty
void on_actionSave_Screenshot_triggered(bool)
MainWindow(QWidget *parent=0)
void on_actionQuit_triggered(bool)
void on_btnReload_clicked()
void on_actionLoad_Viewer_State_triggered(bool)
void on_btnForceStop_clicked()
bool load(const QString &filename)
void on_actionDefault_Background_triggered(bool)
void on_actionWhite_Background_triggered(bool)
Abstract interface for allocating a robust kernel.
virtual RobustKernel * construct()=0
cost for traversing only odometry edges.
const VertexContainer & vertices() const
const Vertex * vertex(size_t i) const
int id() const
returns the id
const EdgeSet & edges() const
const VertexIDMap & vertices() const
void setRobustKernel(RobustKernel *ptr)
RobustKernel * robustKernel() const
if NOT NULL, error of this edge will be robustifed with the kernel
A general case Vertex for optimization.
int dimension() const
dimension of the estimated state belonging to this node
const OptimizableGraph * graph() const
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
void setMarginalized(bool marginalized)
true => this node should be marginalized out during the optimization
create solvers based on their short name
const CreatorList & creatorList() const
return the underlying list of creators
OptimizationAlgorithm * construct(const std::string &tag, OptimizationAlgorithmProperty &solverProperty) const
static OptimizationAlgorithmFactory * instance()
return the instance
std::list< std::shared_ptr< AbstractOptimizationAlgorithmCreator > > CreatorList
Generic interface for a non-linear solver operating on a graph.
const PropertyMap & properties() const
return the properties of the solver
a collection of properties mapping from name to the property itself
void fillKnownKernels(std::vector< std::string > &types) const
AbstractRobustKernelCreator * creator(const std::string &tag) const
static RobustKernelFactory * instance()
return the instance
virtual void setDelta(double delta)
#define __PRETTY_FUNCTION__
std::set< int > dimensions() const
bool isSolverSuitable(const OptimizationAlgorithmProperty &solverProperty, const std::set< int > &vertDims=std::set< int >()) const
describe the properties of a solver
std::string type
type of solver, e.g., "CSparse Cholesky", "PCG"
std::string desc
short description of the solver
int landmarkDim
dimension of the landmark vertices (-1 if variable)
std::string name
name of the solver, e.g., var