1244
2016-06-23 15:20:25 +0000
quaternion exponential logarithm
2019-12-04 15:56:27 +0000
1
1
1
Unclassified
Eigen
Geometry
3.3 (current stable)
All
All
DECISIONNEEDED
Normal
Feature Request
---
1312
814
1
minorlogic
eigen.nobody
chtz
gael.guennebaud
hauke.heibel
jacob.benoit.1
mail
oldest_to_newest
5931
0
minorlogic
2016-06-23 15:20:25 +0000
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;
}
6265
1
minorlogic
2016-09-26 09:56:23 +0000
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);
}
6270
2
gael.guennebaud
2016-09-27 07:17:35 +0000
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<Derived>& vec);
Vector3 QuaternionBase::toAngleAxisVector();
and then think about adding a ctor and operator= as aliases to fromAngleAxisVector?
6272
3
chtz
2016-09-27 08:05:12 +0000
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).
6273
4
minorlogic
2016-09-27 08:48:13 +0000
QuaternionBase::fromAngleAxisVector(const MatrixBase<Derived>& 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
6275
5
minorlogic
2016-09-27 14:46:05 +0000
(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.
6280
6
gael.guennebaud
2016-09-27 22:03:45 +0000
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.
6281
7
gael.guennebaud
2016-09-28 13:40:54 +0000
I forgot to paste the link:
https://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/04/msg00109.html
6282
8
gael.guennebaud
2016-09-28 13:43:08 +0000
That thread is also related:
https://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/05/msg00028.html
6295
9
minorlogic
2016-09-29 13:39:30 +0000
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.
6297
10
chtz
2016-09-29 14:44:45 +0000
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.
6300
11
minorlogic
2016-09-29 15:46:50 +0000
(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.
6413
12
mail
2016-10-20 10:45:20 +0000
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.
6418
13
minorlogic
2016-10-21 08:46:36 +0000
(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?
9688
14
eigen.nobody
2019-12-04 15:56:27 +0000
-- GitLab Migration Automatic Message --
This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.
You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1244.