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

Implement left-Jacobians #116

Open
joansola opened this issue Dec 4, 2019 · 7 comments
Open

Implement left-Jacobians #116

joansola opened this issue Dec 4, 2019 · 7 comments
Labels
enhancement New feature or request

Comments

@joansola
Copy link
Collaborator

joansola commented Dec 4, 2019

This is a low priority issue.

I am wondering: manif could have the option of providing the left-Jacobians instead of the right-Jacobians. This would give extra power to interface it with other tools that might be using left- logic. This means all implementations that regard uncertainties in the global reference.

As a reminder:

  • Local perturbations --> right plus and minus --> right Jacobians
  • Global perturbations --> left plus and minus --> left Jacobians

For example, Delaert and Drummond typically use left operations. Also Ceres uses left-plus in the local parametrizations they ship with the library.

So Manif could easily adapt to these cases.

The option should be global I guess, something like:

  • In the CMAKE step ---> ugly in my opinion
  • As a runtime function manif::options::setRightJacobians() or whatsoever
  • As a flag in the function calls, e.g. X.inverse(J, manif::LEFT_JAC) --> ugly in my opinion
@joansola joansola added the enhancement New feature or request label Dec 4, 2019
@joansola
Copy link
Collaborator Author

joansola commented Dec 4, 2019

For reference:

image

@joansola
Copy link
Collaborator Author

joansola commented Dec 4, 2019

And also:

image

where the strange derivatives in the 3rd row are precisely and respectively the left- and right- Jacobians of Y=f(X)

@artivis
Copy link
Owner

artivis commented Feb 20, 2020

API-wise, another solution could be to rely on different types. In the futur I would like to introduce the Jacobian traits (on branch jacobian_traits) which allows for a semantically nicer notation e.g.:

manif::Jacobian<SE3, SE3> J_Y_X;          // == Eigen::Matrix<double, 6, 6>
manif::Jacobian<SE3, Vector3> J_X_v       // == Eigen::Matrix<double, 6, 3>
manif::Jacobian<Vector3, Vector3> J_vb_va // == Eigen::Matrix<double, 3, 3>

We could go all the way down and create a class Jacobian<LHS, RHS, Type> by inheriting from Eigen::Matrix. The template parameter Type here is an option to either specify left or right Jacobian with default to right.
It would lead to something like

manif::Jacobian<SE3, SE3> right_J_inv_x;
manif::Jacobian<SE3, SE3, manif::Left> left_J_inv_x;
...
X.inverse(right_J_inv_x);
X.inverse(left_J_inv_x);

This implies some heavy modifications but after a quick look I would say it is feasible.

@joansola
Copy link
Collaborator Author

joansola commented Feb 21, 2020

Wow this looks neat!

However, I wonder if it is a good idea to have the left/right thing kind of hidden inside of the matrix template definition. I mean it can be confusing for example for finding bugs once the code is done, because the trace for left/right is perhaps up in some typedef or variable declaration, far from the actual function calls. What do you think?

@artivis
Copy link
Owner

artivis commented May 17, 2020

Late answer...
First I think that my last proposal is best in terms of design and overall 'look'. The alternatives are much less practical or plain ugly (as you pointed).
We could introduce some compile-time sanity checks such that the following would result in a compilation error:
right_J_inv_x * left_J_inv_x ==> Error: You are mixing right and left Jacobians.
Those checks could be in turned off with a compilation flag if someone wants to.

@artivis
Copy link
Owner

artivis commented Jun 9, 2020

Pasting from #132 (comment)

Left vs right Jacobians, #116. Thanks for bringing this up, this is indeed an important discussion. Personally, I have set the development of the control-toolbox set up such that it exclusively uses local perturbations, right plus and minus and right Jacobians. Our main argument why we go down that path is because we are using a family of solvers based on (local) sequential linear-quadratic programming, see e.g. here or here , which are expressed in a differential formulation in their most natural and wide-spread form. Personally, I have made a number of experiments where I compared "global" and "local" formulations. In practice, the "local" formulation does lead to a few advantages, which is why we have almost exculsively adopted that variant.

@artivis
Copy link
Owner

artivis commented Sep 28, 2021

@joansola I've been revisiting this topic and the conclusion is that the designed I proposed a while back (see below) is basically not doable without giving up the use of Eigen::Ref for jacobians arguments, which I believe is something we must keep.

Not doable:

manif::Jacobian<SE3, SE3> right_J_inv_x;
manif::Jacobian<SE3, SE3, manif::Left> left_J_inv_x;
...
X.inverse(right_J_inv_x);
X.inverse(left_J_inv_x);

So back to api design discussion... I really don't know what's best here;

  • In the CMAKE step
  • As a runtime function manif::options::setRightJacobians() or whatsoever
  • As a flag in the function calls, e.g. X.inverse(J, manif::LEFT_JAC)
  • other?

Unfortunately the most practical solution is likely the argument flag X.inverse(J, manif::LEFT_JAC).

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

No branches or pull requests

2 participants