96int main(
int argc,
char** argv) {
102 string inputFilename;
104 string outputfilename;
112 bool listRobustKernels;
114 bool computeMarginals;
120 int hierarchicalDiameter;
121 int updateGraphEachN = 10;
126 arg.
param(
"si", starIterations, 30,
127 "perform n iterations to build the stars");
128 arg.
param(
"hi", highIterations, 100,
129 "perform n iterations to construct the hierarchy");
130 arg.
param(
"li", lowIterations, 100,
"perform n iterations on the low level");
131 arg.
param(
"v", verbose,
false,
"verbose output of the optimization process");
132 arg.
param(
"uThreshold", uThreshold, -1.,
133 "rejection threshold for underdetermined vertices");
134 arg.
param(
"hierarchicalDiameter", hierarchicalDiameter, -1,
135 "selects the diameter of the stars in the hierarchical graph");
136 arg.
param(
"guess", initialGuess,
false,
137 "initial guess based on spanning tree");
140 arg.
param(
"debug", debug,
false,
"print shit load of things for debugging");
141 arg.
param(
"update", updateGraphEachN, 10,
142 "updates after x odometry nodes, (default: 10)");
143 arg.
param(
"guiout", guiOut,
false,
"gui output while running incrementally");
144 arg.
param(
"gnudump", gnudump,
"",
"dump to gnuplot data file");
145 arg.
param(
"robustKernel", robustKernel,
"",
"use this robust error function");
146 arg.
param(
"robustKernelWidth", huberWidth, -1.,
147 "width for the robust Kernel (only if robustKernel)");
148 arg.
param(
"computeMarginals", computeMarginals,
false,
149 "computes the marginal covariances of something. FOR TESTING ONLY");
150 arg.
param(
"huberWidth", huberWidth, -1.,
151 "width for the robust Huber Kernel (only if robustKernel)");
152 arg.
param(
"o", outputfilename,
"",
"output final version of the graph");
153 arg.
param(
"solver", strSolver,
"lm_var_cholmod",
154 "specify which solver to use underneat");
155 arg.
param(
"hsolver", strHSolver,
"gn_var_cholmod",
156 "specify which solver to use for the high level");
157 arg.
param(
"solverlib", dummy,
"",
158 "specify a solver library which will be loaded");
159 arg.
param(
"typeslib", dummy,
"",
160 "specify a types library which will be loaded");
161 arg.
param(
"listTypes", listTypes,
false,
"list the registered types");
162 arg.
param(
"listSolvers", listSolvers,
false,
"list the available solvers");
163 arg.
param(
"listRobustKernels", listRobustKernels,
false,
164 "list the registered robust kernels");
166 arg.
param(
"renameTypes", loadLookup,
"",
167 "create a lookup for loading types into other types,\n\t "
168 "TAG_IN_FILE=INTERNAL_TAG_FOR_TYPE,TAG2=INTERNAL2\n\t e.g., "
169 "VERTEX_CAM=VERTEX_SE3:EXPMAP");
170 arg.
param(
"summary", summaryFile,
"",
171 "append a summary of this optimization run to the summary file "
172 "passed as argument");
174 "graph file which will be processed",
true);
196 if (listRobustKernels) {
197 std::vector<std::string> kernels;
199 cout <<
"Robust Kernels:" << endl;
200 for (
size_t i = 0; i < kernels.size(); ++i) {
201 cout << kernels[i] << endl;
206 if (robustKernel.size() > 0) {
215 if (loadLookup.size() > 0) {
218 if (inputFilename.size() == 0) {
219 cerr <<
"No input data specified" << endl;
221 }
else if (inputFilename ==
"-") {
222 cerr <<
"Read input from stdin" << endl;
223 if (!optimizer.
load(cin)) {
224 cerr <<
"Error loading graph" << endl;
228 cerr <<
"Read input from " << inputFilename << endl;
229 ifstream ifs(inputFilename.c_str());
231 cerr <<
"Failed to open file" << endl;
234 if (!optimizer.
load(ifs)) {
235 cerr <<
"Error loading graph" << endl;
239 cerr <<
"Loaded " << optimizer.
vertices().size() <<
" vertices" << endl;
240 cerr <<
"Loaded " << optimizer.
edges().size() <<
" edges" << endl;
244 if (0 && outputfilename.size() > 0) {
245 cerr <<
"saving " << outputfilename <<
" ... ";
246 ofstream os(outputfilename.c_str());
248 cerr <<
"done." << endl;
255 creator.
addAssociation(
"VERTEX_SE3:QUAT;VERTEX_SE3:QUAT;",
"EDGE_SE3:QUAT");
256 creator.
addAssociation(
"VERTEX_SE3_NEW;VERTEX_SE3_NEW;",
"EDGE_SE3_NEW");
261 if (originalParams) {
262 cerr <<
"ORIGINAL PARAMS" << endl;
264 se3OffsetParam->
setId(100);
266 std::vector<int> depthCamHParamsIds(1);
267 depthCamHParamsIds[0] = se3OffsetParam->
id();
269 "EDGE_SE3_TRACKXYZ", depthCamHParamsIds);
275 if (optimizer.
vertices().size() == 0) {
276 cerr <<
"Graph contains no vertices" << endl;
283 solverFactory->
construct(strSolver, solverProperty);
285 solverFactory->
construct(strHSolver, hsolverProperty);
287 cerr <<
"Error allocating solver. Allocating \"" << strSolver
288 <<
"\" failed!" << endl;
292 cerr <<
"Error allocating hsolver. Allocating \"" << strHSolver
293 <<
"\" failed!" << endl;
297 set<int> vertexDimensions = optimizer.
dimensions();
299 cerr <<
"The selected solver is not suitable for optimizing the given graph"
304 cerr <<
"The selected solver is not suitable for optimizing the given graph"
311 int poseDim = *vertexDimensions.rbegin();
312 string backboneVertexType;
313 string backboneEdgeType;
316 if (hierarchicalDiameter == -1) hierarchicalDiameter = 30;
317 backboneEdgeType =
"EDGE_SE2";
318 backboneVertexType =
"VERTEX_SE2";
319 if (uThreshold < 0) {
324 if (hierarchicalDiameter == -1) hierarchicalDiameter = 4;
325 backboneEdgeType =
"EDGE_SE3:QUAT";
326 backboneVertexType =
"VERTEX_SE3:QUAT";
332 if (uThreshold < 0) {
337 cerr <<
"Fatal: unknown backbone type. The largest vertex dimension is: "
338 << poseDim <<
"." << endl
339 <<
"Exiting." << endl;
351 cerr <<
"# cannot find a vertex to fix in this thing" << endl;
354 cerr <<
"# graph is fixed by node " << gauge->
id() << endl;
358 cerr <<
"# graph is fixed by priors" << endl;
368 cerr <<
CL_RED(
"Warning: d.visited().size() != optimizer.vertices().size()")
370 cerr <<
"visited: " << d.
visited().size() << endl;
371 cerr <<
"vertices: " << optimizer.
vertices().size() << endl;
381 cerr <<
"Initial chi2 = " << FIXED(loadChi) << endl;
391 for (SparseOptimizer::EdgeSet::iterator it = optimizer.
edges().begin();
392 it != optimizer.
edges().end(); ++it) {
395 e->setRobustKernel(kernelCreator->
construct());
396 if (huberWidth > 0) e->robustKernel()->setDelta(huberWidth);
406 backboneEdgeType, backboneVertexType, 0,
407 hierarchicalDiameter, 1, starIterations, uThreshold,
410 cerr <<
"stars computed, stars.size()= " << stars.size() << endl;
412 cerr <<
"hierarchy done, determining border" << endl;
422 for (StarSet::iterator it = stars.begin(); it != stars.end(); ++it) {
424 if (hgauge.empty()) hgauge = s->
gauge();
426 for (HyperGraph::VertexSet::iterator git = s->
gauge().begin();
427 git != s->
gauge().end(); ++git) {
431 for (HyperGraph::EdgeSet::iterator iit = s->
_starEdges.begin();
435 for (
size_t i = 0; i < e->
vertices().size(); i++) {
445 cerr <<
"eset.size()= " << eset.size() << endl;
446 cerr <<
"heset.size()= " << heset.size() << endl;
448 ofstream starStream(
"stars.g2o");
452 ofstream hstarStream(
"hstars.g2o");
456 cerr <<
"stars done!" << endl;
458 cerr <<
"optimizing the high layer" << endl;
459 for (HyperGraph::VertexSet::iterator it = hgauge.begin(); it != hgauge.end();
477 cerr <<
"done" << endl;
479 if (!kernelCreator) {
480 cerr <<
"# Robust error function disabled ";
481 for (SparseOptimizer::EdgeSet::iterator it = optimizer.
edges().begin();
482 it != optimizer.
edges().end(); ++it) {
484 e->setRobustKernel(0);
486 cerr <<
"done." << endl;
488 cerr <<
"# Preparing robust error function ay low level done";
491 cerr <<
"fixing the hstructure, and optimizing the floating nodes" << endl;
492 for (OptimizableGraph::VertexSet::iterator it = hvset.begin();
493 it != hvset.end(); ++it) {
500 cerr <<
"done" << endl;
502 ofstream os(
"debug_low_level.g2o");
506 cerr <<
"adding the original constraints, locking hierarchical solution and "
507 "optimizing the free variables"
509 for (OptimizableGraph::VertexSet::iterator it = vset.begin();
510 it != vset.end(); ++it) {
514 for (HyperGraph::VertexSet::iterator it = hgauge.begin(); it != hgauge.end();
524 cerr <<
"relaxing the full problem" << endl;
525 for (OptimizableGraph::VertexSet::iterator it = vset.begin();
526 it != vset.end(); ++it) {
530 for (HyperGraph::VertexSet::iterator it = hgauge.begin(); it != hgauge.end();
537 int result = optimizer.
optimize(lowIterations);
538 if (result < 0) cerr <<
"failure in low level optimization" << endl;
543 if (summaryFile !=
"") {
551 int maxDim = *vertexDimensions.rbegin();
552 for (HyperGraph::VertexIDMap::iterator it = optimizer.
vertices().begin();
553 it != optimizer.
vertices().end(); ++it) {
563 set<string> edgeTypes;
564 for (HyperGraph::EdgeSet::iterator it = optimizer.
edges().begin();
565 it != optimizer.
edges().end(); ++it) {
567 if (e->
level() == 0) {
572 stringstream edgeTypesString;
573 for (std::set<string>::iterator it = edgeTypes.begin();
574 it != edgeTypes.end(); ++it) {
575 edgeTypesString << *it <<
" ";
596 os.open(summaryFile.c_str(), ios::app);
600 if (outputfilename.size() > 0) {
601 if (outputfilename ==
"-") {
602 cerr <<
"saving to stdout";
605 cerr <<
"saving " << outputfilename <<
" ... ";
606 ofstream os(outputfilename.c_str());
609 cerr <<
"done." << endl;
Abstract interface for allocating a robust kernel.
virtual RobustKernel * construct()=0
Command line parsing of argc and argv.
bool parseArgs(int argc, char **argv, bool exitOnError=true)
void paramLeftOver(const std::string &name, std::string &p, const std::string &defValue, const std::string &desc, bool optional=false)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
Loading libraries during run-time.
void printRegisteredTypes(std::ostream &os, bool comment=false) const
static Factory * instance()
return the instance
const std::string & tag(const HyperGraph::HyperGraphElement *v) const
return the TAG given a vertex
const VertexContainer & vertices() const
int id() const
returns the id
std::set< Edge * > EdgeSet
std::set< Vertex * > VertexSet
const EdgeSet & edges() const
const VertexIDMap & vertices() const
int level() const
returns the level of the edge
A general case Vertex for optimization.
int dimension() const
dimension of the estimated state belonging to this node
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
create solvers based on their short name
OptimizationAlgorithm * construct(const std::string &tag, OptimizationAlgorithmProperty &solverProperty) const
static OptimizationAlgorithmFactory * instance()
return the instance
void listSolvers(std::ostream &os) const
list the known solvers into a stream
Generic interface for a non-linear solver operating on a graph.
a collection of properties mapping from name to the property itself
P * makeProperty(const std::string &name_, const typename P::ValueType &v)
void writeToCSV(std::ostream &os) const
void fillKnownKernels(std::vector< std::string > &types) const
AbstractRobustKernelCreator * creator(const std::string &tag) const
static RobustKernelFactory * instance()
return the instance
void computeActiveErrors()
int optimize(int iterations, bool online=false)
void setForceStopFlag(bool *flag)
void setVerbose(bool verbose)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
virtual void computeInitialGuess()
void setAlgorithm(OptimizationAlgorithm *algorithm)
virtual Vertex * findGauge()
finds a gauge in the graph to remove the undefined dof.
double activeChi2() const
void sigquit_handler(int sig)
#define __PRETTY_FUNCTION__
void computeSimpleStars(StarSet &stars, SparseOptimizer *optimizer, EdgeLabeler *labeler, EdgeCreator *creator, OptimizableGraph::Vertex *gauge_, std::string edgeTag, std::string vertexTag, int level, int step, int backboneIterations, int starIterations, double rejectionThreshold, bool debug)
void computeBorder(StarSet &stars, EdgeStarMap &hesmap)
Property< std::string > StringProperty
void loadStandardTypes(DlWrapper &dlTypesWrapper, int argc, char **argv)
std::set< Star * > StarSet
void loadStandardSolver(DlWrapper &dlSolverWrapper, int argc, char **argv)
std::map< HyperGraph::Edge *, Star * > EdgeStarMap
void constructEdgeStarMap(EdgeStarMap &esmap, StarSet &stars, bool low)
bool addAssociation(const std::string &vertexTypes, const std::string &edgeType)
HyperGraph::VertexSet & visited()
void shortestPaths(HyperGraph::Vertex *v, HyperDijkstra::CostFunction *cost, double maxDistance=std::numeric_limits< double >::max(), double comparisonConditioner=1e-3, bool directed=false, double maxEdgeCost=std::numeric_limits< double >::max())
std::set< int > dimensions() const
bool isSolverSuitable(const OptimizationAlgorithmProperty &solverProperty, const std::set< int > &vertDims=std::set< int >()) const
Parameter * parameter(int id)
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
bool addParameter(Parameter *p)
bool saveSubset(std::ostream &os, HyperGraph::VertexSet &vset, int level=0)
save a subgraph to a stream. Again uses the Factory system.
virtual bool load(std::istream &is)
void setRenamedTypesFromString(const std::string &types)
describe the properties of a solver
HyperGraph::EdgeSet & starFrontierEdges()
edges in the high level that lead to some node owned by a different star
HyperGraph::EdgeSet _starEdges
edges in the star
HyperGraph::VertexSet & gauge()
set of nodes to keep fixed in the optimization
utility functions for handling time related stuff