Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add LM Pose3Example and G2O 3D Reader #85

Merged
merged 9 commits into from
Jun 16, 2020
Merged

Conversation

ProfFan
Copy link
Collaborator

@ProfFan ProfFan commented Jun 15, 2020

No description provided.

@ProfFan
Copy link
Collaborator Author

ProfFan commented Jun 15, 2020

One important note here: the error (referring to the CGLS book Bjorck96) should be calculated as b - Ax

@ProfFan
Copy link
Collaborator Author

ProfFan commented Jun 15, 2020

After 30 GN steps, sphere2500 dataset:
image

Cost 185s of runtime, 30 iterations, cross-module optimization enabled (1.3s, 7 iterations with GTSAM). Since we still do not have a noise model, it's not a particularly fair comparison in number of iterations, but the performance difference in time per iteration is still there (6s v.s. 0.18s)

@marcrasi

Test environment:
macOS 10.15, i7-8700K 4.7GHz

@ProfFan
Copy link
Collaborator Author

ProfFan commented Jun 15, 2020

Add reference to #42

@ProfFan ProfFan requested a review from marcrasi June 15, 2020 22:18
Copy link
Collaborator

@marcrasi marcrasi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! I have some questions, but feel free to merge and we can deal with them in subsequent PRs.

Sources/Benchmarks/Pose3SLAM.swift Outdated Show resolved Hide resolved
Sources/SwiftFusion/Datasets/G2OReader.swift Outdated Show resolved Hide resolved
Sources/SwiftFusion/Datasets/G2OReader.swift Outdated Show resolved Hide resolved
/// | |
/// z-->xZ--> Y (z pointing towards viewer, Z pointing away from viewer)
/// Vehicle at p0 is looking towards y axis (X-axis points towards world y)
func circlePose3(numPoses: Int = 8, radius: Double = 1.0) -> Values {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this create a VariableAssignments directly so that you don't have to convert it later?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified to return (hexagonId, hexagon), but I still feel that Frank may disagree with the current TypedID API as we effectively lost control of what the ID will be.

@@ -62,7 +62,7 @@ public struct NewJacobianFactor<
}

public func errorVector(at x: Variables) -> ErrorVector {
return errorVector_linearComponent(x) + error
return error - errorVector_linearComponent(x)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty confused by the signs.

I see that we need to calculate b - Ax, but I'm not sure if errorVector should be the method that does this.

Changing errorVector to b - Ax changes the meaning of linearization (the comment on NewFactorGraph.linearized implies that errorVector should be Ax + b).

Also, changing errorVector to b - Ax makes it so that errorVector_linearComponent isn't actually the linear component of errorVector and more.

Maybe we should make a new method called residual that calculates b - Ax?

Or we could negate the implementations of errorVector_linearComponent and errorVector_linearComponent_adjoint, and leave errorVector(at: x) = errorVector_linearComponent(x) + error. Then we'd also have to update the comment on NewFactorGraph.linearized to say:

  /// The linear approximation satisfies the approximate equality:
  ///   `self.linearized(at: x).errorVectors(at: dx)` ≈ `self.errorVectors(at: x.moved(along: -1 * dx))`
  /// where the equality is exact when `dx == x.linearizedZero`.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I feel a bit confused too :( IMHO, in CGLS the objective is to reach the solution where Ax=b, thus by moving Ax to the right we have 0 = b - Ax(the "error"). In GN we approximate the L2 error function (which should be >=0) f(x) by its linearization at x0, where f(dx+x_0)=Ax+b (Jacobian A, bias b), and we arrived at the same equation as in CGLS.

I think error here is confusing as it is actually the "error of error", as what we linearized to the JacobianFactor IS the error. However, I am not sure if changing this is actually a good idea, as if we want linear factors to be nonlinear compatible we need the protocol conformances.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonlinear error: |h(x)-z|
linear error |Ax-b|

@ProfFan ProfFan requested a review from dellaert June 16, 2020 14:48
@ProfFan ProfFan merged commit 71bab3b into master Jun 16, 2020
@ProfFan ProfFan deleted the feature/lm_new branch June 16, 2020 18:03
@ProfFan
Copy link
Collaborator Author

ProfFan commented Jun 16, 2020

I merged so we can start using the LM solver right now, and do optimizations later (((

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants