New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Before reporting a bug, please make sure that your Eigen version is up-to-date!
Bug 1244 - quaternion exponential logarithm
quaternion exponential logarithm
 Status: DECISIONNEEDED None Eigen Unclassified Geometry (show other bugs) 3.3 (current stable) All All Normal Feature Request Nobody 1312 3.4 Show dependency tree / graph

 Reported: 2016-06-23 15:20 UTC by Michael Norel 2016-10-21 08:46 UTC (History) 5 users (show) chtz gael.guennebaud hauke.heibel jacob.benoit.1 mail

Attachments

 Michael Norel 2016-06-23 15:20:25 UTC ```For me, it can be useful to have conversions to/from rodrigues parameters from/to quaternions. Usualy it is called " exponential/logarithm" (from lie algebra). As it can be seen in "Sophus" library built on top of Eigen. https://github.com/strasdat/Sophus/blob/master/sophus/so3.hpp My versions of this operations looks like (the SO3 class represent 3 rodrigues params in member m_coeffs ): SO3(const QuaternionT& q_) { // forcing positive "w" to work from 0 to PI const QuaternionT& q = q_.w() >= Scalar(0) ? q_ : QuaternionT(-q_.coeffs()); const Vector3& qv = q.vec(); Scalar sinha = qv.norm(); if(sinha > Scalar(0)) { Scalar angle = Scalar(2) * atan2(sinha, q.w()); //NOTE: signed m_coeffs = qv * (angle/sinha); }else{ // if l is too small, its norm can be equal 0 but norm_inf greater 0 // probably w is much bigger that vec, use it as length m_coeffs = qv * (Scalar(2)/q.w()); ////NOTE: signed } } NOTE: it is important to keep rodrigues params inside (0 ...PI) interval for precision. Also all handmade taylor expansions of SINC is not useful and have no better precision than direct computation. QuaternionT getQuaternion() const { QuaternionT q; const Vector3 ha = m_coeffs/Scalar(2); // vector of half angle Scalar l = ha.norm(); if( l > Scalar(0) ) { Scalar ss = sin(l)/l; q = QuaternionT(cos(l), ha.x()*ss, ha.y()*ss, ha.z()*ss); }else{ // if l is too small, its norm can be equal 0 but norm_inf greater 0 q = QuaternionT(Scalar(1), ha.x(), ha.y(), ha.z()); } return q; }``` Michael Norel 2016-09-26 09:56:23 UTC ```UPD: more compact version of "Lie 2 Quat" conversion, with same precision QuaternionT getQuaternion() const { Scalar a = m_coeffs.norm(); Scalar ha = a * Scalar(0.5); Scalar scale = a > Scalar(0) ? sin(ha) / a : Scalar(0.5); return QuaternionT(cos(ha), x() * scale, y() * scale, z() * scale); }``` Gael Guennebaud 2016-09-27 07:17:35 UTC ```Those are essentially variants of the current AngleAxis <-> Quaternion conversion methods where the angle is embedded in the norm of the rotation axis. The main question is about the API. We could start with: QuaternionBase::fromAngleAxisVector(const MatrixBase& vec); Vector3 QuaternionBase::toAngleAxisVector(); and then think about adding a ctor and operator= as aliases to fromAngleAxisVector?``` Christoph Hertzberg 2016-09-27 08:05:12 UTC `I usually know it by the name "Scaled Axis", so I'd prefer fromScaledAxis(...), etc. I don't really like adding operator= and a constructor for thi conversion, since it would hide what is happening there (this is not the only possible map from R^3 to S^3).` Michael Norel 2016-09-27 08:48:13 UTC ```QuaternionBase::fromAngleAxisVector(const MatrixBase& vec); Vector3 QuaternionBase::toAngleAxisVector(); This sounds for me very confusing. It is not common "term". Common terms (for me) from computer vision is: 1. Exponential map https://en.wikipedia.org/wiki/Rotation_matrix#Exponential_map https://en.wikipedia.org/wiki/Rotation_group_SO(3)#Exponential_map 2. Rodrigues parameters https://en.wikipedia.org/wiki/Rotation_formalisms_in_three_dimensions#Rodrigues_parameters_and_Gibbs_representation 3. Lie parameters 4. Logarithm/exponent or tangent. https://pixhawk.org/_media/dev/know-how/jlblanco2010geometry3d_techrep.pdf chapter "SE(3) as a Lie group" For example openCV uses Rodrigues "term", Sophus uses SE3::exp(..) and SE3::log(..) as static member functions. Also "AngleAxis" usualy mean exactly Angle + Axis, and it is hard to discover that so named functions works with lie params. This operations and representations is common for computer vision, 3d reconstruction. Please assume this set of names: fromRodrigues toRodrigues fromExpMap toExpMap fromLie toLie exp log logarithmicMap exponentialGroup logarithm exponent fromTangent toTangent i prefer: log exp or logarithm exponent``` Michael Norel 2016-09-27 14:46:05 UTC ```(In reply to Christoph Hertzberg from comment #3) > I don't really like adding operator= and a > constructor for thi conversion, since it would hide what is happening there > (this is not the only possible map from R^3 to S^3). I agree, it is not "common" operation for creation of quaternion, and can be mixed up with "Euler angles" etc. i prefer some similar way that uses "FromTwoVectors" member.``` Gael Guennebaud 2016-09-27 22:03:45 UTC ```I agree my naming suggestion was pretty bad. Nonetheless, I still think that we should put the emphasis on the *representation* of the input/output using names matching: FromRepresentationName fromRepresentationName toRepresentationName According to: https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation, and some other resources, choice for RepresentationName could be: - RotationVector - EulerVector plus the ScaleAxis proposal of Christoph. Among those three, I would slightly prefer RotationVector: - ScaleAxis does not convey the idea of a rotation - EulerVector might be confused with a vector storing Euler angles. - RotationVector might be confused with RotationAxis, but then fromRotationAxis would make no sense, and toRotationVector does return the rotation axis (it's just that it is not normalized). See also this old thread for an extensive discussion and proposals for the proper introduction of Lie group and algebra their exp/log maps.``` Gael Guennebaud 2016-09-28 13:40:54 UTC ```I forgot to paste the link: https://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/04/msg00109.html``` Gael Guennebaud 2016-09-28 13:43:08 UTC ```That thread is also related: https://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/05/msg00028.html``` Michael Norel 2016-09-29 13:39:30 UTC ```Note: - RotationVector https://en.wikipedia.org/wiki/Rotation_(mathematics) - EulerVector https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation Give correct description from google, but - ScaleAxis not.``` Christoph Hertzberg 2016-09-29 14:44:45 UTC ```I did say "Scaled Axis" not "Scale Axis", but admittedly that was mostly the common naming at my former group (however there are several positive google hits for that name as well). But I don't have strong feelings for that name. Given the other options I'd prefer RotationVector over EulerVector. I don't think the confusion risk with RotationAxis is too big in contrast to the danger of confusing EulerVector with EulerAngles. The bad thing is that for small angles they agree (with Euler angles in XYZ convention), get slightly different for medium angles and are completely off, when the Euler angles are near their singularities.``` Michael Norel 2016-09-29 15:46:50 UTC ```(In reply to Christoph Hertzberg from comment #10) I agree, EulerVector will be mixed up with Euler angles. And RotationVector sound better among 3 versions.``` Adrian Haarbach 2016-10-20 10:45:20 UTC ```I am using these implementations of quaternion exp and log mapping: https://github.com/hengli/vmav-ros-pkg/blob/master/calibration/hand_eye_calibration/include/hand_eye_calibration/QuaternionMapping.h These also work for non-unit quaternions. If bug 560 is solved in 3.3, one could just add them to the API of the GeneralQuaternion interface and, if needed, add the more specialized exp/log implementations for unit quaternions that were discussed above to the UnitQuaternion interface.``` Michael Norel 2016-10-21 08:46:36 UTC ```(In reply to Adrian Haarbach from comment #12) Seems it little bit different functionality with additional performance loose. Don't you think it is better to use as overloaded "exp/log" functions for exact "math" interpretation of "exp/log"? P.S. did you tried the "boost::quaternion" implementation of their quaternion operations?```

 Note You need to log in before you can comment on or make changes to this bug.