Quaternion Ordering

1,985 views
Skip to first unread message

Lloyd Hughes

unread,
Mar 15, 2014, 4:17:11 AM3/15/14
to ceres-...@googlegroups.com
Hi,

I was wondering what the reasoning behind the quaternion ordering in Ceres is, as it breaks compatibility with Eigen's Quaternion class. Eigen use the w x y z ordering but this is stored in memory as a double array [x, y, z, w]

Is there any easy way to change this?

Thanks

Sameer Agarwal

unread,
Mar 15, 2014, 12:15:20 PM3/15/14
to ceres-...@googlegroups.com
Hi Lloyd,

I understand this is a painpoint, but the problem here is in Eigen not ceres. [w, x, y, z] is a standard representation for quaternions. Most mathematics is written in that form too. At this point there is far too much code that depends on that representation in and outside google that I cannot change the representation based on Eigen's design choices. That said, if you look inside include/ceres/rotation.h you will find most of what you need to work with quaternions. And if something is missing we are accepting patches :)

Sameer






--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/81464590-8710-4e56-b6c9-d20fd84a3e3f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Greg Coombe

unread,
Mar 17, 2014, 1:20:05 PM3/17/14
to ceres-...@googlegroups.com
Eigen has made some poor choices about quaternion ordering. You need to be careful because the constructor ordering is [w, x, y, z], and the coeffs() ordering ordering is [x, y, z, w].

I think I saw a discussion on their mailing list that this was Matlab's fault.


Lloyd Hughes

unread,
Mar 26, 2014, 7:50:54 AM3/26/14
to ceres-...@googlegroups.com
Hi,

I am using all the ceres rotations and everything. The only reason this is an issue is that all my code uses Eigen. Thus when I want to use ceres I have to make a new double array with the correct ordering, pass this to ceres, then after optimization I need to update all the Eigen Quaternion components again. 

Is there any way around doing this? If ceres use Eigen, then why is their ordering different underneath?

Thanks

Lloyd

Sameer Agarwal

unread,
Mar 26, 2014, 8:17:18 AM3/26/14
to ceres-...@googlegroups.com
Lloyd,

I am using all the ceres rotations and everything. The only reason this is an issue is that all my code uses Eigen. Thus when I want to use ceres I have to make a new double array with the correct ordering, pass this to ceres, then after optimization I need to update all the Eigen Quaternion components again. 

Is there any way around doing this?

The only thing preventing you from using the quaternion ordering that eigen has is the quaternionparameterization which makes assumptions about how the elements are ordered. You can define your own quaternionparameterization which is eigen compatible and you should be good to go. You can use the existing one as the basis of your implementation.

It may even be a good idea to add an EigenQuaternionParameterization object to local_parameterization.h
 
If ceres use Eigen, then why is their ordering different underneath?

Eigen is a rather large library. Ceres' use of Eigen is limited to its linear algebra API.

Sameer

 

Lloyd Hughes

unread,
Mar 28, 2014, 6:11:48 AM3/28/14
to ceres-...@googlegroups.com
Hi Sameer,

I will create EigenQuaternionParameterization. 

Thanks 

Lloyd

Alex Stewart

unread,
Mar 28, 2014, 6:27:26 AM3/28/14
to ceres-...@googlegroups.com
Lloyd,

You might want to look at Sophus: https://github.com/stevenlovegrove/Sophus from Hauke Strasdat & Steven Lovegrove

It's a nice library for working with transformations that's now fully templated, and thus can be used in Ceres autodiff cost functions.  It also uses, and integrates well with Eigen.  There is also an example of using it with Ceres in the tests.

-Alex

Lloyd

unread,
Apr 15, 2014, 1:29:40 PM4/15/14
to ceres-...@googlegroups.com
Hi all,

I have added a few functions to support Eigen quaternions. I haven't tested them all yet, but have a look at the repo on my github. I added them to a separate namespace too just for the project I am currently busy with, I might create a pull request once I know they all work. If anyone wants to check them and create the pull request that is also fine.


Hope it helps someone.

Sameer Agarwal

unread,
Apr 15, 2014, 1:33:43 PM4/15/14
to ceres-...@googlegroups.com
Lloyd this is great. one thing I am wondering about is, if you are using Eigen quaternion, then why not use Eigen's quaternion functions for actually doing the rotation operation etc.

Why implement them all over again? Ceres jets can be used as a scalar type for eigen types.

Sameer



Lloyd

unread,
Apr 17, 2014, 4:13:09 AM4/17/14
to ceres-...@googlegroups.com
Hi Sameer,

Good point. I wasn't aware I could use the Eigen functions on ceres Jets. I will give it a shot. That will be far better than reimplementing those functions.

Thanks for the pointers.

Lloyd

unread,
Apr 18, 2014, 6:44:19 AM4/18/14
to ceres-...@googlegroups.com
Hi Sameer,

I am battling to use the Eigen functions with ceres::Jet scalar type. The main problem is that I can't seem to map the cost parameters to an Eigen Vector. I have this: 

Eigen::Quaterniond q;

bool operator()(const T* const point, T* residuals) const {

      Eigen::Matrix<ceres::Jet<T,3>,3> p;

     p = q * Eigen::Map<const Eigen::Matrix< ceres::Jet<T,3>, 3, 1>>;

}

Could you please guide me as to the correct way to approach this? 

Henrique Mendonça

unread,
Apr 18, 2014, 7:35:21 AM4/18/14
to ceres-solver
Hi Lloyd,

I'm not sure what are your dimensions here but I don't think you need to call Jet directly inside your cost function.
I use something like that:
    typedef Eigen::Matrix<T, 3, 1> Vector3;
    typedef Eigen::Map<const Vector3> Vector3Ref;

Hope it helps,
Henrique


Sameer Agarwal

unread,
Apr 18, 2014, 10:09:14 AM4/18/14
to ceres-...@googlegroups.com
Henrique is right. You should not be specifying the size of the internal jets. The actual size depends on all the parameters being used by a cost function.

Sameer



Lloyd

unread,
Apr 21, 2014, 4:36:48 AM4/21/14
to ceres-...@googlegroups.com
Thanks, I see what I was doing wrong. It appears to be working now.
Reply all
Reply to author
Forward
0 new messages