91 int main(
int argc,
char** argv)
101 string outputfilename;
109 bool listRobustKernels;
111 bool computeMarginals;
117 int hierarchicalDiameter;
118 int updateGraphEachN = 10;
123 arg.
param(
"si", starIterations, 30,
"perform n iterations to build the stars");
124 arg.
param(
"hi", highIterations, 100,
"perform n iterations to construct the hierarchy");
125 arg.
param(
"li", lowIterations, 100,
"perform n iterations on the low level");
126 arg.
param(
"v", verbose,
false,
"verbose output of the optimization process");
127 arg.
param(
"uThreshold", uThreshold, -1.,
"rejection threshold for underdetermined vertices");
128 arg.
param(
"hierarchicalDiameter", hierarchicalDiameter, -1 ,
"selects the diameter of the stars in the hierarchical graph");
129 arg.
param(
"guess", initialGuess,
false,
"initial guess based on spanning tree");
131 arg.
param(
"debug", debug,
false,
"print shit load of things for debugging");
132 arg.
param(
"update", updateGraphEachN, 10,
"updates after x odometry nodes, (default: 10)");
133 arg.
param(
"guiout", guiOut,
false,
"gui output while running incrementally");
134 arg.
param(
"gnudump", gnudump,
"",
"dump to gnuplot data file");
135 arg.
param(
"robustKernel", robustKernel,
"",
"use this robust error function");
136 arg.
param(
"robustKernelWidth", huberWidth, -1.,
"width for the robust Kernel (only if robustKernel)");
137 arg.
param(
"computeMarginals", computeMarginals,
false,
"computes the marginal covariances of something. FOR TESTING ONLY");
138 arg.
param(
"huberWidth", huberWidth, -1.,
"width for the robust Huber Kernel (only if robustKernel)");
139 arg.
param(
"o", outputfilename,
"",
"output final version of the graph");
140 arg.
param(
"solver", strSolver,
"lm_var_cholmod",
"specify which solver to use underneat");
141 arg.
param(
"hsolver", strHSolver,
"gn_var_cholmod",
"specify which solver to use for the high level");
142 arg.
param(
"solverlib", dummy,
"",
"specify a solver library which will be loaded");
143 arg.
param(
"typeslib", dummy,
"",
"specify a types library which will be loaded");
144 arg.
param(
"listTypes", listTypes,
false,
"list the registered types");
145 arg.
param(
"listSolvers", listSolvers,
false,
"list the available solvers");
146 arg.
param(
"listRobustKernels", listRobustKernels,
false,
"list the registered robust kernels");
148 arg.
param(
"renameTypes", loadLookup,
"",
"create a lookup for loading types into other types,\n\t TAG_IN_FILE=INTERNAL_TAG_FOR_TYPE,TAG2=INTERNAL2\n\t e.g., VERTEX_CAM=VERTEX_SE3:EXPMAP");
149 arg.
param(
"summary", summaryFile,
"",
"append a summary of this optimization run to the summary file passed as argument");
150 arg.
paramLeftOver(
"graph-input", inputFilename,
"",
"graph file which will be processed",
true);
169 Factory::instance()->printRegisteredTypes(cout,
true);
172 if (listRobustKernels) {
173 std::vector<std::string> kernels;
174 RobustKernelFactory::instance()->fillKnownKernels(kernels);
175 cout <<
"Robust Kernels:" << endl;
176 for (
size_t i = 0; i < kernels.size(); ++i) {
177 cout << kernels[i] << endl;
182 if (robustKernel.size() > 0) {
183 kernelCreator = RobustKernelFactory::instance()->creator(robustKernel);
191 if (loadLookup.size() > 0) {
194 if (inputFilename.size() == 0) {
195 cerr <<
"No input data specified" << endl;
197 }
else if (inputFilename ==
"-") {
198 cerr <<
"Read input from stdin" << endl;
199 if (!optimizer.
load(cin)) {
200 cerr <<
"Error loading graph" << endl;
204 cerr <<
"Read input from " << inputFilename << endl;
205 ifstream ifs(inputFilename.c_str());
207 cerr <<
"Failed to open file" << endl;
210 if (!optimizer.
load(ifs)) {
211 cerr <<
"Error loading graph" << endl;
215 cerr <<
"Loaded " << optimizer.
vertices().size() <<
" vertices" << endl;
216 cerr <<
"Loaded " << optimizer.
edges().size() <<
" edges" << endl;
219 OptimizableGraph::EdgeSet originalEdges=optimizer.
edges();
221 if (0 && outputfilename.size() > 0) {
222 cerr <<
"saving " << outputfilename <<
" ... ";
223 ofstream os(outputfilename.c_str());
225 cerr <<
"done." << endl;
232 creator.
addAssociation(
"VERTEX_SE3:QUAT;VERTEX_SE3:QUAT;",
"EDGE_SE3:QUAT");
233 creator.
addAssociation(
"VERTEX_SE3_NEW;VERTEX_SE3_NEW;",
"EDGE_SE3_NEW");
238 if (originalParams) {
239 cerr <<
"ORIGINAL PARAMS" << endl;
241 se3OffsetParam->
setId(100);
243 std::vector<int> depthCamHParamsIds(1);
244 depthCamHParamsIds[0]=se3OffsetParam->
id();
245 creator.
addAssociation(
"VERTEX_SE3:QUAT;VERTEX_TRACKXYZ;",
"EDGE_SE3_TRACKXYZ", depthCamHParamsIds);
251 if (optimizer.
vertices().size() == 0) {
252 cerr <<
"Graph contains no vertices" << endl;
261 cerr <<
"Error allocating solver. Allocating \"" << strSolver <<
"\" failed!" << endl;
265 cerr <<
"Error allocating hsolver. Allocating \"" << strHSolver <<
"\" failed!" << endl;
269 set<int> vertexDimensions = optimizer.
dimensions();
271 cerr <<
"The selected solver is not suitable for optimizing the given graph" << endl;
275 cerr <<
"The selected solver is not suitable for optimizing the given graph" << endl;
281 int poseDim=*vertexDimensions.rbegin();
282 string backboneVertexType;
283 string backboneEdgeType;
286 if (hierarchicalDiameter == -1)
287 hierarchicalDiameter = 30;
288 backboneEdgeType =
"EDGE_SE2";
289 backboneVertexType =
"VERTEX_SE2";
295 if (hierarchicalDiameter == -1)
296 hierarchicalDiameter = 4;
297 backboneEdgeType =
"EDGE_SE3:QUAT";
298 backboneVertexType =
"VERTEX_SE3:QUAT";
309 cerr <<
"Fatal: unknown backbone type. The largest vertex dimension is: " << poseDim <<
"." << endl
310 <<
"Exiting." << endl;
326 cerr <<
"# cannot find a vertex to fix in this thing" << endl;
329 cerr <<
"# graph is fixed by node " << gauge->
id() << endl;
333 cerr <<
"# graph is fixed by priors" << endl;
348 cerr <<
CL_RED(
"Warning: d.visited().size() != optimizer.vertices().size()") << endl;
349 cerr <<
"visited: " << d.
visited().size() << endl;
350 cerr <<
"vertices: " << optimizer.
vertices().size() << endl;
361 cerr <<
"Initial chi2 = " << FIXED(loadChi) << endl;
373 for (SparseOptimizer::EdgeSet::iterator it = optimizer.
edges().begin(); it != optimizer.
edges().end(); ++it) {
374 SparseOptimizer::Edge* e =
dynamic_cast<SparseOptimizer::Edge*
>(*it);
376 e->setRobustKernel(kernelCreator->
construct());
378 e->robustKernel()->setDelta(huberWidth);
390 gauge, backboneEdgeType, backboneVertexType, 0, hierarchicalDiameter,
391 1, starIterations, uThreshold, debug);
393 cerr <<
"stars computed, stars.size()= " << stars.size() << endl;
395 cerr <<
"hierarchy done, determining border" << endl;
400 OptimizableGraph::EdgeSet eset;
401 OptimizableGraph::VertexSet vset;
402 OptimizableGraph::EdgeSet heset;
403 OptimizableGraph::VertexSet hvset;
405 for (StarSet::iterator it=stars.begin(); it!=stars.end(); it++) {
411 for (HyperGraph::VertexSet::iterator git=s->
gauge().begin();
412 git != s->
gauge().end(); git++) {
419 for (
size_t i=0; i<e->
vertices().size(); i++){
428 cerr <<
"eset.size()= " << eset.size() << endl;
429 cerr <<
"heset.size()= " << heset.size() << endl;
431 ofstream starStream(
"stars.g2o");
435 ofstream hstarStream(
"hstars.g2o");
439 cerr <<
"stars done!" << endl;
441 cerr <<
"optimizing the high layer" << endl;
442 for (HyperGraph::VertexSet::iterator it = hgauge.begin(); it!=hgauge.end(); it++){
460 cerr <<
"done" << endl;
463 if (! kernelCreator) {
464 cerr <<
"# Robust error function disabled ";
465 for (SparseOptimizer::EdgeSet::iterator it = optimizer.
edges().begin(); it != optimizer.
edges().end(); ++it) {
466 SparseOptimizer::Edge* e =
dynamic_cast<SparseOptimizer::Edge*
>(*it);
467 e->setRobustKernel(0);
469 cerr <<
"done." << endl;
471 cerr <<
"# Preparing robust error function ay low level done";
474 cerr <<
"fixing the hstructure, and optimizing the floating nodes" << endl;
475 for (OptimizableGraph::VertexSet::iterator it = hvset.begin(); it!=hvset.end(); it++){
482 cerr <<
"done" << endl;
484 ofstream os(
"debug_low_level.g2o");
489 cerr <<
"adding the original constraints, locking hierarchical solution and optimizing the free variables" << endl;
490 for (OptimizableGraph::VertexSet::iterator it = vset.begin(); it!=vset.end(); it++){
494 for (HyperGraph::VertexSet::iterator it = hgauge.begin(); it!=hgauge.end(); it++){
504 cerr <<
"relaxing the full problem" << endl;
505 for (OptimizableGraph::VertexSet::iterator it = vset.begin(); it!=vset.end(); it++){
509 for (HyperGraph::VertexSet::iterator it = hgauge.begin(); it!=hgauge.end(); it++){
515 int result = optimizer.
optimize(lowIterations);
517 cerr <<
"failure in low level optimization" << endl;
522 if (summaryFile!=
"") {
529 int maxDim = *vertexDimensions.rbegin();
530 for (HyperGraph::VertexIDMap::iterator it=optimizer.
vertices().begin(); it!=optimizer.
vertices().end(); it++){
539 set<string> edgeTypes;
540 for (HyperGraph::EdgeSet::iterator it=optimizer.
edges().begin(); it!=optimizer.
edges().end(); it++){
543 edgeTypes.insert(Factory::instance()->tag(e));
547 stringstream edgeTypesString;
548 for (std::set<string>::iterator it=edgeTypes.begin(); it!=edgeTypes.end(); it++){
549 edgeTypesString << *it <<
" ";
571 os.open(summaryFile.c_str(), ios::app);
576 if (outputfilename.size() > 0) {
577 if (outputfilename ==
"-") {
578 cerr <<
"saving to stdout";
581 cerr <<
"saving " << outputfilename <<
" ... ";
582 ofstream os(outputfilename.c_str());
585 cerr <<
"done." << endl;
virtual void computeInitialGuess()
int id() const
returns the id
#define __PRETTY_FUNCTION__
Command line parsing of argc and argv.
HyperGraph::VertexSet & visited()
Abstract interface for allocating a robust kernel.
describe the properties of a solver
void loadStandardTypes(DlWrapper &dlTypesWrapper, int argc, char **argv)
void constructEdgeStarMap(EdgeStarMap &esmap, StarSet &stars, bool low)
std::set< Vertex * > VertexSet
HyperGraph::EdgeSet & starFrontierEdges()
edges in the high level that lead to some node owned by a different star
int optimize(int iterations, bool online=false)
int level() const
returns the level of the edge
void computeActiveErrors()
create solvers based on their short name
const VertexIDMap & vertices() const
void computeBorder(StarSet &stars, EdgeStarMap &hesmap)
utility functions for handling time related stuff
virtual Vertex * findGauge()
finds a gauge in the graph to remove the undefined dof.
int dimension() const
dimension of the estimated state belonging to this node
P * makeProperty(const std::string &name_, const typename P::ValueType &v)
HyperGraph::EdgeSet _starEdges
edges in the star
const VertexContainer & vertices() const
bool parseArgs(int argc, char **argv, bool exitOnError=true)
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
bool isSolverSuitable(const OptimizationAlgorithmProperty &solverProperty, const std::set< int > &vertDims=std::set< int >()) const
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())
void setVerbose(bool verbose)
int main(int argc, char **argv)
const EdgeSet & edges() const
bool saveSubset(std::ostream &os, HyperGraph::VertexSet &vset, int level=0)
save a subgraph to a stream. Again uses the Factory system.
void setForceStopFlag(bool *flag)
void paramLeftOver(const std::string &name, std::string &p, const std::string &defValue, const std::string &desc, bool optional=false)
void setAlgorithm(OptimizationAlgorithm *algorithm)
void sigquit_handler(int sig)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
std::set< Star * > StarSet
void writeToCSV(std::ostream &os) const
bool addParameter(Parameter *p)
std::map< HyperGraph::Edge *, Star * > EdgeStarMap
void listSolvers(std::ostream &os) const
list the known solvers into a stream
void loadStandardSolver(DlWrapper &dlSolverWrapper, int argc, char **argv)
A general case Vertex for optimization.
Loading libraries during run-time.
void setRenamedTypesFromString(const std::string &types)
virtual bool load(std::istream &is, bool createEdges=true)
load the graph from a stream. Uses the Factory singleton for creating the vertices and edges...
Parameter * parameter(int id)
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)
HyperGraph::VertexSet & gauge()
set of nodes to keep fixed in the optimization
virtual RobustKernel * construct()=0
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
a collection of properties mapping from name to the property itself
Generic interface for a non-linear solver operating on a graph.
std::set< int > dimensions() const
OptimizationAlgorithm * construct(const std::string &tag, OptimizationAlgorithmProperty &solverProperty) const
double activeChi2() const
bool addAssociation(const std::string &vertexTypes, const std::string &edgeType)