Incremental vs Batch FixedLagSmoother

53 views
Skip to first unread message

Joel Truher

unread,
Jun 11, 2026, 1:12:29 PMJun 11
to gtsam users
Hi everybody,

I'm making progress on using GTSAM in Java for the FRC 2d localization problem.

I've been using the BatchFixedLagSmoother, using factors for odometry, vision, and gyro, and it works fine in simulation.

This morning I tried swapping in the IncrementalFixedLagSmoother, because I imagined it would be a faster, drop-in replacement.  It did not work well at all.  It produces incorrect, uncertain estimates for awhile, and then aborts with IndeterminantLinearSystemException.  I can make it "work" by supplying the ground-truth pose as the initial value.

Does anyone have advice about the use of these two smoothers?  Is the incremental one supposed to be so sensitive to initial values?  Are there other limitations or best-practices I should be aware of?  Should I just use the batch one?

Thanks!

Joel

Dellaert, Frank

unread,
Jun 12, 2026, 9:08:47 AMJun 12
to Joel Truher, gtsam users
Hmmm, would be good to get to the bottom of that. 
One thing you could try when it runs into an indeterminate linear system is to do a batch optimization with Gauss-Newton on exactly the same measurements. If that fails, you have a truly underdetermined system. 
FD

--
You received this message because you are subscribed to the Google Groups "gtsam users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gtsam-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/gtsam-users/d57f99d0-914d-4219-93f6-1b5534a4d0a2n%40googlegroups.com.

Joel Truher

unread,
Jun 17, 2026, 2:28:52 PMJun 17
to gtsam users
OK, I've dug a little deeper.  It seems that I completely do not understand ISAM2.

If I set up a simple one-shot problem with GenericProjectionFactor, with a few (tight-prior) landmarks and a single (loose-prior) pose, and appropriate pixel measurements, the Gauss Newton solver works fine.

GaussNewtonOptimizer optimizer(graph(), initial());
Values result = optimizer.optimize();

Giving the same problem to ISAM2 yields nothing useful, it just returns the initial values.

ISAM2 isam2;
isam2.update(graph(), initial());
Values result = isam2.calculateBestEstimate();

I must be doing something terribly wrong here.  Can you advise?

José Luis Blanco-Claraco

unread,
Jun 17, 2026, 5:37:23 PMJun 17
to Joel Truher, gtsam users
Hi Joel:

iSAM2 is tricky to use :-)

Try to add additional update() calls before getting the estimate:

ISAM2 isam2;
isam2.update(graph(), initial());
for (int i=0;i<3;i++) {
isam2.update();
}
Values result = isam2.calculateBestEstimate();

Or at least one update().
Also, try reducing the relinearization thresholds:

ISAM2Params params;
params.relinearizeThreshold = 0.01;
params.relinearizeSkip = 1;
ISAM2 isam2(params);

Hope it helps...
JL
> To view this discussion visit https://groups.google.com/d/msgid/gtsam-users/119d8799-061d-46ab-a255-92af8cfb633en%40googlegroups.com.



--

/**
* Jose Luis Blanco-Claraco
* Universidad de Almería - Departamento de Ingeniería
* [Homepage]( https://w3.ual.es/~jlblanco/ )
* [GH profile]( https://github.com/jlblancoc )
*/

Joel Truher

unread,
Jun 18, 2026, 12:15:41 AMJun 18
to gtsam users
Oh!  That does indeed make my example work, thank you!

For the larger real case (many poses, many landmarks, many cameras), it still misbehaves in fascinating ways.  I'll come back to it after the batch version is in prod.

Thank you for your help!
Reply all
Reply to author
Forward
0 new messages